Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.
This commit is contained in:
2
node_modules/astro/dist/core/app/common.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/app/common.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { SSRManifest, SerializedSSRManifest } from './types.js';
|
||||
export declare function deserializeManifest(serializedManifest: SerializedSSRManifest): SSRManifest;
|
37
node_modules/astro/dist/core/app/common.js
generated
vendored
Normal file
37
node_modules/astro/dist/core/app/common.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import { decodeKey } from "../encryption.js";
|
||||
import { NOOP_MIDDLEWARE_FN } from "../middleware/noop-middleware.js";
|
||||
import { deserializeRouteData } from "../routing/manifest/serialization.js";
|
||||
function deserializeManifest(serializedManifest) {
|
||||
const routes = [];
|
||||
for (const serializedRoute of serializedManifest.routes) {
|
||||
routes.push({
|
||||
...serializedRoute,
|
||||
routeData: deserializeRouteData(serializedRoute.routeData)
|
||||
});
|
||||
const route = serializedRoute;
|
||||
route.routeData = deserializeRouteData(serializedRoute.routeData);
|
||||
}
|
||||
const assets = new Set(serializedManifest.assets);
|
||||
const componentMetadata = new Map(serializedManifest.componentMetadata);
|
||||
const inlinedScripts = new Map(serializedManifest.inlinedScripts);
|
||||
const clientDirectives = new Map(serializedManifest.clientDirectives);
|
||||
const serverIslandNameMap = new Map(serializedManifest.serverIslandNameMap);
|
||||
const key = decodeKey(serializedManifest.key);
|
||||
return {
|
||||
// in case user middleware exists, this no-op middleware will be reassigned (see plugin-ssr.ts)
|
||||
middleware() {
|
||||
return { onRequest: NOOP_MIDDLEWARE_FN };
|
||||
},
|
||||
...serializedManifest,
|
||||
assets,
|
||||
componentMetadata,
|
||||
inlinedScripts,
|
||||
clientDirectives,
|
||||
routes,
|
||||
serverIslandNameMap,
|
||||
key
|
||||
};
|
||||
}
|
||||
export {
|
||||
deserializeManifest
|
||||
};
|
9
node_modules/astro/dist/core/app/createOutgoingHttpHeaders.d.ts
generated
vendored
Normal file
9
node_modules/astro/dist/core/app/createOutgoingHttpHeaders.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { OutgoingHttpHeaders } from 'node:http';
|
||||
/**
|
||||
* Takes in a nullable WebAPI Headers object and produces a NodeJS OutgoingHttpHeaders object suitable for usage
|
||||
* with ServerResponse.writeHead(..) or ServerResponse.setHeader(..)
|
||||
*
|
||||
* @param headers WebAPI Headers object
|
||||
* @returns {OutgoingHttpHeaders} NodeJS OutgoingHttpHeaders object with multiple set-cookie handled as an array of values
|
||||
*/
|
||||
export declare const createOutgoingHttpHeaders: (headers: Headers | undefined | null) => OutgoingHttpHeaders | undefined;
|
19
node_modules/astro/dist/core/app/createOutgoingHttpHeaders.js
generated
vendored
Normal file
19
node_modules/astro/dist/core/app/createOutgoingHttpHeaders.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
const createOutgoingHttpHeaders = (headers) => {
|
||||
if (!headers) {
|
||||
return void 0;
|
||||
}
|
||||
const nodeHeaders = Object.fromEntries(headers.entries());
|
||||
if (Object.keys(nodeHeaders).length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
if (headers.has("set-cookie")) {
|
||||
const cookieHeaders = headers.getSetCookie();
|
||||
if (cookieHeaders.length > 1) {
|
||||
nodeHeaders["set-cookie"] = cookieHeaders;
|
||||
}
|
||||
}
|
||||
return nodeHeaders;
|
||||
};
|
||||
export {
|
||||
createOutgoingHttpHeaders
|
||||
};
|
73
node_modules/astro/dist/core/app/index.d.ts
generated
vendored
Normal file
73
node_modules/astro/dist/core/app/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
import type { ManifestData, RouteData, SSRManifest } from '../../@types/astro.js';
|
||||
import { getSetCookiesFromResponse } from '../cookies/index.js';
|
||||
import { AstroIntegrationLogger } from '../logger/core.js';
|
||||
export { deserializeManifest } from './common.js';
|
||||
export interface RenderOptions {
|
||||
/**
|
||||
* Whether to automatically add all cookies written by `Astro.cookie.set()` to the response headers.
|
||||
*
|
||||
* When set to `true`, they will be added to the `Set-Cookie` header as comma-separated key=value pairs. You can use the standard `response.headers.getSetCookie()` API to read them individually.
|
||||
*
|
||||
* When set to `false`, the cookies will only be available from `App.getSetCookieFromResponse(response)`.
|
||||
*
|
||||
* @default {false}
|
||||
*/
|
||||
addCookieHeader?: boolean;
|
||||
/**
|
||||
* The client IP address that will be made available as `Astro.clientAddress` in pages, and as `ctx.clientAddress` in API routes and middleware.
|
||||
*
|
||||
* Default: `request[Symbol.for("astro.clientAddress")]`
|
||||
*/
|
||||
clientAddress?: string;
|
||||
/**
|
||||
* The mutable object that will be made available as `Astro.locals` in pages, and as `ctx.locals` in API routes and middleware.
|
||||
*/
|
||||
locals?: object;
|
||||
/**
|
||||
* **Advanced API**: you probably do not need to use this.
|
||||
*
|
||||
* Default: `app.match(request)`
|
||||
*/
|
||||
routeData?: RouteData;
|
||||
}
|
||||
export interface RenderErrorOptions {
|
||||
locals?: App.Locals;
|
||||
routeData?: RouteData;
|
||||
response?: Response;
|
||||
status: 404 | 500;
|
||||
/**
|
||||
* Whether to skip middleware while rendering the error page. Defaults to false.
|
||||
*/
|
||||
skipMiddleware?: boolean;
|
||||
/**
|
||||
* Allows passing an error to 500.astro. It will be available through `Astro.props.error`.
|
||||
*/
|
||||
error?: unknown;
|
||||
}
|
||||
export declare class App {
|
||||
#private;
|
||||
constructor(manifest: SSRManifest, streaming?: boolean);
|
||||
getAdapterLogger(): AstroIntegrationLogger;
|
||||
set setManifestData(newManifestData: ManifestData);
|
||||
removeBase(pathname: string): string;
|
||||
match(request: Request): RouteData | undefined;
|
||||
render(request: Request, options?: RenderOptions): Promise<Response>;
|
||||
/**
|
||||
* @deprecated Instead of passing `RouteData` and locals individually, pass an object with `routeData` and `locals` properties.
|
||||
* See https://github.com/withastro/astro/pull/9199 for more information.
|
||||
*/
|
||||
render(request: Request, routeData?: RouteData, locals?: object): Promise<Response>;
|
||||
setCookieHeaders(response: Response): Generator<string, string[], any>;
|
||||
/**
|
||||
* Reads all the cookies written by `Astro.cookie.set()` onto the passed response.
|
||||
* For example,
|
||||
* ```ts
|
||||
* for (const cookie_ of App.getSetCookieFromResponse(response)) {
|
||||
* const cookie: string = cookie_
|
||||
* }
|
||||
* ```
|
||||
* @param response The response to read cookies from.
|
||||
* @returns An iterator that yields key-value pairs as equal-sign-separated strings.
|
||||
*/
|
||||
static getSetCookieFromResponse: typeof getSetCookiesFromResponse;
|
||||
}
|
372
node_modules/astro/dist/core/app/index.js
generated
vendored
Normal file
372
node_modules/astro/dist/core/app/index.js
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
import { normalizeTheLocale } from "../../i18n/index.js";
|
||||
import {
|
||||
REROUTABLE_STATUS_CODES,
|
||||
REROUTE_DIRECTIVE_HEADER,
|
||||
clientAddressSymbol,
|
||||
clientLocalsSymbol,
|
||||
responseSentSymbol
|
||||
} from "../constants.js";
|
||||
import { getSetCookiesFromResponse } from "../cookies/index.js";
|
||||
import { AstroError, AstroErrorData } from "../errors/index.js";
|
||||
import { consoleLogDestination } from "../logger/console.js";
|
||||
import { AstroIntegrationLogger, Logger } from "../logger/core.js";
|
||||
import { NOOP_MIDDLEWARE_FN } from "../middleware/noop-middleware.js";
|
||||
import {
|
||||
appendForwardSlash,
|
||||
joinPaths,
|
||||
prependForwardSlash,
|
||||
removeTrailingForwardSlash
|
||||
} from "../path.js";
|
||||
import { RenderContext } from "../render-context.js";
|
||||
import { createAssetLink } from "../render/ssr-element.js";
|
||||
import { createDefaultRoutes, injectDefaultRoutes } from "../routing/default.js";
|
||||
import { matchRoute } from "../routing/match.js";
|
||||
import { AppPipeline } from "./pipeline.js";
|
||||
import { deserializeManifest } from "./common.js";
|
||||
class App {
|
||||
#manifest;
|
||||
#manifestData;
|
||||
#logger = new Logger({
|
||||
dest: consoleLogDestination,
|
||||
level: "info"
|
||||
});
|
||||
#baseWithoutTrailingSlash;
|
||||
#pipeline;
|
||||
#adapterLogger;
|
||||
#renderOptionsDeprecationWarningShown = false;
|
||||
constructor(manifest, streaming = true) {
|
||||
this.#manifest = manifest;
|
||||
this.#manifestData = injectDefaultRoutes(manifest, {
|
||||
routes: manifest.routes.map((route) => route.routeData)
|
||||
});
|
||||
this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base);
|
||||
this.#pipeline = this.#createPipeline(this.#manifestData, streaming);
|
||||
this.#adapterLogger = new AstroIntegrationLogger(
|
||||
this.#logger.options,
|
||||
this.#manifest.adapterName
|
||||
);
|
||||
}
|
||||
getAdapterLogger() {
|
||||
return this.#adapterLogger;
|
||||
}
|
||||
/**
|
||||
* Creates a pipeline by reading the stored manifest
|
||||
*
|
||||
* @param manifestData
|
||||
* @param streaming
|
||||
* @private
|
||||
*/
|
||||
#createPipeline(manifestData, streaming = false) {
|
||||
return AppPipeline.create(manifestData, {
|
||||
logger: this.#logger,
|
||||
manifest: this.#manifest,
|
||||
mode: "production",
|
||||
renderers: this.#manifest.renderers,
|
||||
defaultRoutes: createDefaultRoutes(this.#manifest),
|
||||
resolve: async (specifier) => {
|
||||
if (!(specifier in this.#manifest.entryModules)) {
|
||||
throw new Error(`Unable to resolve [${specifier}]`);
|
||||
}
|
||||
const bundlePath = this.#manifest.entryModules[specifier];
|
||||
if (bundlePath.startsWith("data:") || bundlePath.length === 0) {
|
||||
return bundlePath;
|
||||
} else {
|
||||
return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix);
|
||||
}
|
||||
},
|
||||
serverLike: true,
|
||||
streaming
|
||||
});
|
||||
}
|
||||
set setManifestData(newManifestData) {
|
||||
this.#manifestData = newManifestData;
|
||||
}
|
||||
removeBase(pathname) {
|
||||
if (pathname.startsWith(this.#manifest.base)) {
|
||||
return pathname.slice(this.#baseWithoutTrailingSlash.length + 1);
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
#getPathnameFromRequest(request) {
|
||||
const url = new URL(request.url);
|
||||
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
||||
return pathname;
|
||||
}
|
||||
match(request) {
|
||||
const url = new URL(request.url);
|
||||
if (this.#manifest.assets.has(url.pathname)) return void 0;
|
||||
let pathname = this.#computePathnameFromDomain(request);
|
||||
if (!pathname) {
|
||||
pathname = prependForwardSlash(this.removeBase(url.pathname));
|
||||
}
|
||||
let routeData = matchRoute(pathname, this.#manifestData);
|
||||
if (!routeData || routeData.prerender) return void 0;
|
||||
return routeData;
|
||||
}
|
||||
#computePathnameFromDomain(request) {
|
||||
let pathname = void 0;
|
||||
const url = new URL(request.url);
|
||||
if (this.#manifest.i18n && (this.#manifest.i18n.strategy === "domains-prefix-always" || this.#manifest.i18n.strategy === "domains-prefix-other-locales" || this.#manifest.i18n.strategy === "domains-prefix-always-no-redirect")) {
|
||||
let host = request.headers.get("X-Forwarded-Host");
|
||||
let protocol = request.headers.get("X-Forwarded-Proto");
|
||||
if (protocol) {
|
||||
protocol = protocol + ":";
|
||||
} else {
|
||||
protocol = url.protocol;
|
||||
}
|
||||
if (!host) {
|
||||
host = request.headers.get("Host");
|
||||
}
|
||||
if (host && protocol) {
|
||||
host = host.split(":")[0];
|
||||
try {
|
||||
let locale;
|
||||
const hostAsUrl = new URL(`${protocol}//${host}`);
|
||||
for (const [domainKey, localeValue] of Object.entries(
|
||||
this.#manifest.i18n.domainLookupTable
|
||||
)) {
|
||||
const domainKeyAsUrl = new URL(domainKey);
|
||||
if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) {
|
||||
locale = localeValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (locale) {
|
||||
pathname = prependForwardSlash(
|
||||
joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname))
|
||||
);
|
||||
if (url.pathname.endsWith("/")) {
|
||||
pathname = appendForwardSlash(pathname);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.#logger.error(
|
||||
"router",
|
||||
`Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`
|
||||
);
|
||||
this.#logger.error("router", `Error: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
async render(request, routeDataOrOptions, maybeLocals) {
|
||||
let routeData;
|
||||
let locals;
|
||||
let clientAddress;
|
||||
let addCookieHeader;
|
||||
if (routeDataOrOptions && ("addCookieHeader" in routeDataOrOptions || "clientAddress" in routeDataOrOptions || "locals" in routeDataOrOptions || "routeData" in routeDataOrOptions)) {
|
||||
if ("addCookieHeader" in routeDataOrOptions) {
|
||||
addCookieHeader = routeDataOrOptions.addCookieHeader;
|
||||
}
|
||||
if ("clientAddress" in routeDataOrOptions) {
|
||||
clientAddress = routeDataOrOptions.clientAddress;
|
||||
}
|
||||
if ("routeData" in routeDataOrOptions) {
|
||||
routeData = routeDataOrOptions.routeData;
|
||||
}
|
||||
if ("locals" in routeDataOrOptions) {
|
||||
locals = routeDataOrOptions.locals;
|
||||
}
|
||||
} else {
|
||||
routeData = routeDataOrOptions;
|
||||
locals = maybeLocals;
|
||||
if (routeDataOrOptions || locals) {
|
||||
this.#logRenderOptionsDeprecationWarning();
|
||||
}
|
||||
}
|
||||
if (routeData) {
|
||||
this.#logger.debug(
|
||||
"router",
|
||||
"The adapter " + this.#manifest.adapterName + " provided a custom RouteData for ",
|
||||
request.url
|
||||
);
|
||||
this.#logger.debug("router", "RouteData:\n" + routeData);
|
||||
}
|
||||
if (locals) {
|
||||
if (typeof locals !== "object") {
|
||||
const error = new AstroError(AstroErrorData.LocalsNotAnObject);
|
||||
this.#logger.error(null, error.stack);
|
||||
return this.#renderError(request, { status: 500, error });
|
||||
}
|
||||
Reflect.set(request, clientLocalsSymbol, locals);
|
||||
}
|
||||
if (clientAddress) {
|
||||
Reflect.set(request, clientAddressSymbol, clientAddress);
|
||||
}
|
||||
if (!routeData) {
|
||||
routeData = this.match(request);
|
||||
this.#logger.debug("router", "Astro matched the following route for " + request.url);
|
||||
this.#logger.debug("router", "RouteData:\n" + routeData);
|
||||
}
|
||||
if (!routeData) {
|
||||
this.#logger.debug("router", "Astro hasn't found routes that match " + request.url);
|
||||
this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData);
|
||||
return this.#renderError(request, { locals, status: 404 });
|
||||
}
|
||||
const pathname = this.#getPathnameFromRequest(request);
|
||||
const defaultStatus = this.#getDefaultStatusCode(routeData, pathname);
|
||||
let response;
|
||||
try {
|
||||
const mod = await this.#pipeline.getModuleForRoute(routeData);
|
||||
const renderContext = await RenderContext.create({
|
||||
pipeline: this.#pipeline,
|
||||
locals,
|
||||
pathname,
|
||||
request,
|
||||
routeData,
|
||||
status: defaultStatus
|
||||
});
|
||||
response = await renderContext.render(await mod.page());
|
||||
} catch (err) {
|
||||
this.#logger.error(null, err.stack || err.message || String(err));
|
||||
return this.#renderError(request, { locals, status: 500, error: err });
|
||||
}
|
||||
if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
|
||||
return this.#renderError(request, {
|
||||
locals,
|
||||
response,
|
||||
status: response.status,
|
||||
// We don't have an error to report here. Passing null means we pass nothing intentionally
|
||||
// while undefined means there's no error
|
||||
error: response.status === 500 ? null : void 0
|
||||
});
|
||||
}
|
||||
if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
|
||||
response.headers.delete(REROUTE_DIRECTIVE_HEADER);
|
||||
}
|
||||
if (addCookieHeader) {
|
||||
for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) {
|
||||
response.headers.append("set-cookie", setCookieHeaderValue);
|
||||
}
|
||||
}
|
||||
Reflect.set(response, responseSentSymbol, true);
|
||||
return response;
|
||||
}
|
||||
#logRenderOptionsDeprecationWarning() {
|
||||
if (this.#renderOptionsDeprecationWarningShown) return;
|
||||
this.#logger.warn(
|
||||
"deprecated",
|
||||
`The adapter ${this.#manifest.adapterName} is using a deprecated signature of the 'app.render()' method. From Astro 4.0, locals and routeData are provided as properties on an optional object to this method. Using the old signature will cause an error in Astro 5.0. See https://github.com/withastro/astro/pull/9199 for more information.`
|
||||
);
|
||||
this.#renderOptionsDeprecationWarningShown = true;
|
||||
}
|
||||
setCookieHeaders(response) {
|
||||
return getSetCookiesFromResponse(response);
|
||||
}
|
||||
/**
|
||||
* Reads all the cookies written by `Astro.cookie.set()` onto the passed response.
|
||||
* For example,
|
||||
* ```ts
|
||||
* for (const cookie_ of App.getSetCookieFromResponse(response)) {
|
||||
* const cookie: string = cookie_
|
||||
* }
|
||||
* ```
|
||||
* @param response The response to read cookies from.
|
||||
* @returns An iterator that yields key-value pairs as equal-sign-separated strings.
|
||||
*/
|
||||
static getSetCookieFromResponse = getSetCookiesFromResponse;
|
||||
/**
|
||||
* If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro).
|
||||
* This also handles pre-rendered /404 or /500 routes
|
||||
*/
|
||||
async #renderError(request, {
|
||||
locals,
|
||||
status,
|
||||
response: originalResponse,
|
||||
skipMiddleware = false,
|
||||
error
|
||||
}) {
|
||||
const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`;
|
||||
const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
|
||||
const url = new URL(request.url);
|
||||
if (errorRouteData) {
|
||||
if (errorRouteData.prerender) {
|
||||
const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : "";
|
||||
const statusURL = new URL(
|
||||
`${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`,
|
||||
url
|
||||
);
|
||||
if (statusURL.toString() !== request.url) {
|
||||
const response2 = await fetch(statusURL.toString());
|
||||
const override = { status };
|
||||
return this.#mergeResponses(response2, originalResponse, override);
|
||||
}
|
||||
}
|
||||
const mod = await this.#pipeline.getModuleForRoute(errorRouteData);
|
||||
try {
|
||||
const renderContext = await RenderContext.create({
|
||||
locals,
|
||||
pipeline: this.#pipeline,
|
||||
middleware: skipMiddleware ? NOOP_MIDDLEWARE_FN : void 0,
|
||||
pathname: this.#getPathnameFromRequest(request),
|
||||
request,
|
||||
routeData: errorRouteData,
|
||||
status,
|
||||
props: { error }
|
||||
});
|
||||
const response2 = await renderContext.render(await mod.page());
|
||||
return this.#mergeResponses(response2, originalResponse);
|
||||
} catch {
|
||||
if (skipMiddleware === false) {
|
||||
return this.#renderError(request, {
|
||||
locals,
|
||||
status,
|
||||
response: originalResponse,
|
||||
skipMiddleware: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const response = this.#mergeResponses(new Response(null, { status }), originalResponse);
|
||||
Reflect.set(response, responseSentSymbol, true);
|
||||
return response;
|
||||
}
|
||||
#mergeResponses(newResponse, originalResponse, override) {
|
||||
if (!originalResponse) {
|
||||
if (override !== void 0) {
|
||||
return new Response(newResponse.body, {
|
||||
status: override.status,
|
||||
statusText: newResponse.statusText,
|
||||
headers: newResponse.headers
|
||||
});
|
||||
}
|
||||
return newResponse;
|
||||
}
|
||||
const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status;
|
||||
try {
|
||||
originalResponse.headers.delete("Content-type");
|
||||
} catch {
|
||||
}
|
||||
return new Response(newResponse.body, {
|
||||
status,
|
||||
statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
|
||||
// If you're looking at here for possible bugs, it means that it's not a bug.
|
||||
// With the middleware, users can meddle with headers, and we should pass to the 404/500.
|
||||
// If users see something weird, it's because they are setting some headers they should not.
|
||||
//
|
||||
// Although, we don't want it to replace the content-type, because the error page must return `text/html`
|
||||
headers: new Headers([
|
||||
...Array.from(newResponse.headers),
|
||||
...Array.from(originalResponse.headers)
|
||||
])
|
||||
});
|
||||
}
|
||||
#getDefaultStatusCode(routeData, pathname) {
|
||||
if (!routeData.pattern.test(pathname)) {
|
||||
for (const fallbackRoute of routeData.fallbackRoutes) {
|
||||
if (fallbackRoute.pattern.test(pathname)) {
|
||||
return 302;
|
||||
}
|
||||
}
|
||||
}
|
||||
const route = removeTrailingForwardSlash(routeData.route);
|
||||
if (route.endsWith("/404")) return 404;
|
||||
if (route.endsWith("/500")) return 500;
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
export {
|
||||
App,
|
||||
deserializeManifest
|
||||
};
|
7
node_modules/astro/dist/core/app/middlewares.d.ts
generated
vendored
Normal file
7
node_modules/astro/dist/core/app/middlewares.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { MiddlewareHandler } from '../../@types/astro.js';
|
||||
/**
|
||||
* Returns a middleware function in charge to check the `origin` header.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export declare function createOriginCheckMiddleware(): MiddlewareHandler;
|
44
node_modules/astro/dist/core/app/middlewares.js
generated
vendored
Normal file
44
node_modules/astro/dist/core/app/middlewares.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { defineMiddleware } from "../middleware/index.js";
|
||||
const FORM_CONTENT_TYPES = [
|
||||
"application/x-www-form-urlencoded",
|
||||
"multipart/form-data",
|
||||
"text/plain"
|
||||
];
|
||||
function createOriginCheckMiddleware() {
|
||||
return defineMiddleware((context, next) => {
|
||||
const { request, url } = context;
|
||||
if (request.method === "GET") {
|
||||
return next();
|
||||
}
|
||||
const sameOrigin = (request.method === "POST" || request.method === "PUT" || request.method === "PATCH" || request.method === "DELETE") && request.headers.get("origin") === url.origin;
|
||||
const hasContentType = request.headers.has("content-type");
|
||||
if (hasContentType) {
|
||||
const formLikeHeader = hasFormLikeHeader(request.headers.get("content-type"));
|
||||
if (formLikeHeader && !sameOrigin) {
|
||||
return new Response(`Cross-site ${request.method} form submissions are forbidden`, {
|
||||
status: 403
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!sameOrigin) {
|
||||
return new Response(`Cross-site ${request.method} form submissions are forbidden`, {
|
||||
status: 403
|
||||
});
|
||||
}
|
||||
}
|
||||
return next();
|
||||
});
|
||||
}
|
||||
function hasFormLikeHeader(contentType) {
|
||||
if (contentType) {
|
||||
for (const FORM_CONTENT_TYPE of FORM_CONTENT_TYPES) {
|
||||
if (contentType.toLowerCase().includes(FORM_CONTENT_TYPE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export {
|
||||
createOriginCheckMiddleware
|
||||
};
|
56
node_modules/astro/dist/core/app/node.d.ts
generated
vendored
Normal file
56
node_modules/astro/dist/core/app/node.d.ts
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
import type { RouteData } from '../../@types/astro.js';
|
||||
import { App } from './index.js';
|
||||
import type { RenderOptions } from './index.js';
|
||||
import type { SSRManifest } from './types.js';
|
||||
export { apply as applyPolyfills } from '../polyfill.js';
|
||||
/**
|
||||
* Allow the request body to be explicitly overridden. For example, this
|
||||
* is used by the Express JSON middleware.
|
||||
*/
|
||||
interface NodeRequest extends IncomingMessage {
|
||||
body?: unknown;
|
||||
}
|
||||
export declare class NodeApp extends App {
|
||||
match(req: NodeRequest | Request): RouteData | undefined;
|
||||
render(request: NodeRequest | Request, options?: RenderOptions): Promise<Response>;
|
||||
/**
|
||||
* @deprecated Instead of passing `RouteData` and locals individually, pass an object with `routeData` and `locals` properties.
|
||||
* See https://github.com/withastro/astro/pull/9199 for more information.
|
||||
*/
|
||||
render(request: NodeRequest | Request, routeData?: RouteData, locals?: object): Promise<Response>;
|
||||
/**
|
||||
* Converts a NodeJS IncomingMessage into a web standard Request.
|
||||
* ```js
|
||||
* import { NodeApp } from 'astro/app/node';
|
||||
* import { createServer } from 'node:http';
|
||||
*
|
||||
* const server = createServer(async (req, res) => {
|
||||
* const request = NodeApp.createRequest(req);
|
||||
* const response = await app.render(request);
|
||||
* await NodeApp.writeResponse(response, res);
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
static createRequest(req: NodeRequest, { skipBody }?: {
|
||||
skipBody?: boolean | undefined;
|
||||
}): Request;
|
||||
/**
|
||||
* Streams a web-standard Response into a NodeJS Server Response.
|
||||
* ```js
|
||||
* import { NodeApp } from 'astro/app/node';
|
||||
* import { createServer } from 'node:http';
|
||||
*
|
||||
* const server = createServer(async (req, res) => {
|
||||
* const request = NodeApp.createRequest(req);
|
||||
* const response = await app.render(request);
|
||||
* await NodeApp.writeResponse(response, res);
|
||||
* })
|
||||
* ```
|
||||
* @param source WhatWG Response
|
||||
* @param destination NodeJS ServerResponse
|
||||
*/
|
||||
static writeResponse(source: Response, destination: ServerResponse): Promise<ServerResponse<IncomingMessage> | undefined>;
|
||||
}
|
||||
export declare function loadManifest(rootFolder: URL): Promise<SSRManifest>;
|
||||
export declare function loadApp(rootFolder: URL): Promise<NodeApp>;
|
167
node_modules/astro/dist/core/app/node.js
generated
vendored
Normal file
167
node_modules/astro/dist/core/app/node.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
import fs from "node:fs";
|
||||
import { Http2ServerResponse } from "node:http2";
|
||||
import { clientAddressSymbol } from "../constants.js";
|
||||
import { deserializeManifest } from "./common.js";
|
||||
import { createOutgoingHttpHeaders } from "./createOutgoingHttpHeaders.js";
|
||||
import { App } from "./index.js";
|
||||
import { apply } from "../polyfill.js";
|
||||
class NodeApp extends App {
|
||||
match(req) {
|
||||
if (!(req instanceof Request)) {
|
||||
req = NodeApp.createRequest(req, {
|
||||
skipBody: true
|
||||
});
|
||||
}
|
||||
return super.match(req);
|
||||
}
|
||||
render(req, routeDataOrOptions, maybeLocals) {
|
||||
if (!(req instanceof Request)) {
|
||||
req = NodeApp.createRequest(req);
|
||||
}
|
||||
return super.render(req, routeDataOrOptions, maybeLocals);
|
||||
}
|
||||
/**
|
||||
* Converts a NodeJS IncomingMessage into a web standard Request.
|
||||
* ```js
|
||||
* import { NodeApp } from 'astro/app/node';
|
||||
* import { createServer } from 'node:http';
|
||||
*
|
||||
* const server = createServer(async (req, res) => {
|
||||
* const request = NodeApp.createRequest(req);
|
||||
* const response = await app.render(request);
|
||||
* await NodeApp.writeResponse(response, res);
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
static createRequest(req, { skipBody = false } = {}) {
|
||||
const isEncrypted = "encrypted" in req.socket && req.socket.encrypted;
|
||||
const getFirstForwardedValue = (multiValueHeader) => {
|
||||
return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0];
|
||||
};
|
||||
const forwardedProtocol = getFirstForwardedValue(req.headers["x-forwarded-proto"]);
|
||||
const protocol = forwardedProtocol ?? (isEncrypted ? "https" : "http");
|
||||
const forwardedHostname = getFirstForwardedValue(req.headers["x-forwarded-host"]);
|
||||
const hostname = forwardedHostname ?? req.headers.host ?? req.headers[":authority"];
|
||||
const port = getFirstForwardedValue(req.headers["x-forwarded-port"]);
|
||||
const portInHostname = typeof hostname === "string" && /:\d+$/.test(hostname);
|
||||
const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`;
|
||||
const url = `${protocol}://${hostnamePort}${req.url}`;
|
||||
const options = {
|
||||
method: req.method || "GET",
|
||||
headers: makeRequestHeaders(req)
|
||||
};
|
||||
const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false;
|
||||
if (bodyAllowed) {
|
||||
Object.assign(options, makeRequestBody(req));
|
||||
}
|
||||
const request = new Request(url, options);
|
||||
const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]);
|
||||
const clientIp = forwardedClientIp || req.socket?.remoteAddress;
|
||||
if (clientIp) {
|
||||
Reflect.set(request, clientAddressSymbol, clientIp);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
/**
|
||||
* Streams a web-standard Response into a NodeJS Server Response.
|
||||
* ```js
|
||||
* import { NodeApp } from 'astro/app/node';
|
||||
* import { createServer } from 'node:http';
|
||||
*
|
||||
* const server = createServer(async (req, res) => {
|
||||
* const request = NodeApp.createRequest(req);
|
||||
* const response = await app.render(request);
|
||||
* await NodeApp.writeResponse(response, res);
|
||||
* })
|
||||
* ```
|
||||
* @param source WhatWG Response
|
||||
* @param destination NodeJS ServerResponse
|
||||
*/
|
||||
static async writeResponse(source, destination) {
|
||||
const { status, headers, body, statusText } = source;
|
||||
if (!(destination instanceof Http2ServerResponse)) {
|
||||
destination.statusMessage = statusText;
|
||||
}
|
||||
destination.writeHead(status, createOutgoingHttpHeaders(headers));
|
||||
if (!body) return destination.end();
|
||||
try {
|
||||
const reader = body.getReader();
|
||||
destination.on("close", () => {
|
||||
reader.cancel().catch((err) => {
|
||||
console.error(
|
||||
`There was an uncaught error in the middle of the stream while rendering ${destination.req.url}.`,
|
||||
err
|
||||
);
|
||||
});
|
||||
});
|
||||
let result = await reader.read();
|
||||
while (!result.done) {
|
||||
destination.write(result.value);
|
||||
result = await reader.read();
|
||||
}
|
||||
destination.end();
|
||||
} catch (err) {
|
||||
destination.write("Internal server error", () => {
|
||||
err instanceof Error ? destination.destroy(err) : destination.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function makeRequestHeaders(req) {
|
||||
const headers = new Headers();
|
||||
for (const [name, value] of Object.entries(req.headers)) {
|
||||
if (value === void 0) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
for (const item of value) {
|
||||
headers.append(name, item);
|
||||
}
|
||||
} else {
|
||||
headers.append(name, value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
function makeRequestBody(req) {
|
||||
if (req.body !== void 0) {
|
||||
if (typeof req.body === "string" && req.body.length > 0) {
|
||||
return { body: Buffer.from(req.body) };
|
||||
}
|
||||
if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) {
|
||||
return { body: Buffer.from(JSON.stringify(req.body)) };
|
||||
}
|
||||
if (typeof req.body === "object" && req.body !== null && typeof req.body[Symbol.asyncIterator] !== "undefined") {
|
||||
return asyncIterableToBodyProps(req.body);
|
||||
}
|
||||
}
|
||||
return asyncIterableToBodyProps(req);
|
||||
}
|
||||
function asyncIterableToBodyProps(iterable) {
|
||||
return {
|
||||
// Node uses undici for the Request implementation. Undici accepts
|
||||
// a non-standard async iterable for the body.
|
||||
// @ts-expect-error
|
||||
body: iterable,
|
||||
// The duplex property is required when using a ReadableStream or async
|
||||
// iterable for the body. The type definitions do not include the duplex
|
||||
// property because they are not up-to-date.
|
||||
duplex: "half"
|
||||
};
|
||||
}
|
||||
async function loadManifest(rootFolder) {
|
||||
const manifestFile = new URL("./manifest.json", rootFolder);
|
||||
const rawManifest = await fs.promises.readFile(manifestFile, "utf-8");
|
||||
const serializedManifest = JSON.parse(rawManifest);
|
||||
return deserializeManifest(serializedManifest);
|
||||
}
|
||||
async function loadApp(rootFolder) {
|
||||
const manifest = await loadManifest(rootFolder);
|
||||
return new NodeApp(manifest);
|
||||
}
|
||||
export {
|
||||
NodeApp,
|
||||
apply as applyPolyfills,
|
||||
loadApp,
|
||||
loadManifest
|
||||
};
|
12
node_modules/astro/dist/core/app/pipeline.d.ts
generated
vendored
Normal file
12
node_modules/astro/dist/core/app/pipeline.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { ComponentInstance, ManifestData, RewritePayload, RouteData, SSRResult } from '../../@types/astro.js';
|
||||
import { Pipeline, type TryRewriteResult } from '../base-pipeline.js';
|
||||
import type { SinglePageBuiltModule } from '../build/types.js';
|
||||
export declare class AppPipeline extends Pipeline {
|
||||
#private;
|
||||
static create(manifestData: ManifestData, { logger, manifest, mode, renderers, resolve, serverLike, streaming, defaultRoutes, }: Pick<AppPipeline, 'logger' | 'manifest' | 'mode' | 'renderers' | 'resolve' | 'serverLike' | 'streaming' | 'defaultRoutes'>): AppPipeline;
|
||||
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'>;
|
||||
componentMetadata(): void;
|
||||
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
||||
tryRewrite(payload: RewritePayload, request: Request): Promise<TryRewriteResult>;
|
||||
getModuleForRoute(route: RouteData): Promise<SinglePageBuiltModule>;
|
||||
}
|
106
node_modules/astro/dist/core/app/pipeline.js
generated
vendored
Normal file
106
node_modules/astro/dist/core/app/pipeline.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
import { Pipeline } from "../base-pipeline.js";
|
||||
import { RedirectSinglePageBuiltModule } from "../redirects/component.js";
|
||||
import { createModuleScriptElement, createStylesheetElementSet } from "../render/ssr-element.js";
|
||||
import { findRouteToRewrite } from "../routing/rewrite.js";
|
||||
class AppPipeline extends Pipeline {
|
||||
#manifestData;
|
||||
static create(manifestData, {
|
||||
logger,
|
||||
manifest,
|
||||
mode,
|
||||
renderers,
|
||||
resolve,
|
||||
serverLike,
|
||||
streaming,
|
||||
defaultRoutes
|
||||
}) {
|
||||
const pipeline = new AppPipeline(
|
||||
logger,
|
||||
manifest,
|
||||
mode,
|
||||
renderers,
|
||||
resolve,
|
||||
serverLike,
|
||||
streaming,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
defaultRoutes
|
||||
);
|
||||
pipeline.#manifestData = manifestData;
|
||||
return pipeline;
|
||||
}
|
||||
headElements(routeData) {
|
||||
const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
|
||||
const links = /* @__PURE__ */ new Set();
|
||||
const scripts = /* @__PURE__ */ new Set();
|
||||
const styles = createStylesheetElementSet(routeInfo?.styles ?? []);
|
||||
for (const script of routeInfo?.scripts ?? []) {
|
||||
if ("stage" in script) {
|
||||
if (script.stage === "head-inline") {
|
||||
scripts.add({
|
||||
props: {},
|
||||
children: script.children
|
||||
});
|
||||
}
|
||||
} else {
|
||||
scripts.add(createModuleScriptElement(script));
|
||||
}
|
||||
}
|
||||
return { links, styles, scripts };
|
||||
}
|
||||
componentMetadata() {
|
||||
}
|
||||
async getComponentByRoute(routeData) {
|
||||
const module = await this.getModuleForRoute(routeData);
|
||||
return module.page();
|
||||
}
|
||||
async tryRewrite(payload, request) {
|
||||
const { newUrl, pathname, routeData } = findRouteToRewrite({
|
||||
payload,
|
||||
request,
|
||||
routes: this.manifest?.routes.map((r) => r.routeData),
|
||||
trailingSlash: this.manifest.trailingSlash,
|
||||
buildFormat: this.manifest.buildFormat,
|
||||
base: this.manifest.base
|
||||
});
|
||||
const componentInstance = await this.getComponentByRoute(routeData);
|
||||
return { newUrl, pathname, componentInstance, routeData };
|
||||
}
|
||||
async getModuleForRoute(route) {
|
||||
for (const defaultRoute of this.defaultRoutes) {
|
||||
if (route.component === defaultRoute.component) {
|
||||
return {
|
||||
page: () => Promise.resolve(defaultRoute.instance),
|
||||
renderers: []
|
||||
};
|
||||
}
|
||||
}
|
||||
if (route.type === "redirect") {
|
||||
return RedirectSinglePageBuiltModule;
|
||||
} else {
|
||||
if (this.manifest.pageMap) {
|
||||
const importComponentInstance = this.manifest.pageMap.get(route.component);
|
||||
if (!importComponentInstance) {
|
||||
throw new Error(
|
||||
`Unexpectedly unable to find a component instance for route ${route.route}`
|
||||
);
|
||||
}
|
||||
return await importComponentInstance();
|
||||
} else if (this.manifest.pageModule) {
|
||||
return this.manifest.pageModule;
|
||||
}
|
||||
throw new Error(
|
||||
"Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
AppPipeline
|
||||
};
|
77
node_modules/astro/dist/core/app/types.d.ts
generated
vendored
Normal file
77
node_modules/astro/dist/core/app/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
import type { AstroMiddlewareInstance, ComponentInstance, Locales, RouteData, SSRComponentMetadata, SSRLoadedRenderer, SSRResult, SerializedRouteData } from '../../@types/astro.js';
|
||||
import type { RoutingStrategies } from '../../i18n/utils.js';
|
||||
import type { SinglePageBuiltModule } from '../build/types.js';
|
||||
export type ComponentPath = string;
|
||||
export type StylesheetAsset = {
|
||||
type: 'inline';
|
||||
content: string;
|
||||
} | {
|
||||
type: 'external';
|
||||
src: string;
|
||||
};
|
||||
export interface RouteInfo {
|
||||
routeData: RouteData;
|
||||
file: string;
|
||||
links: string[];
|
||||
scripts: ({
|
||||
children: string;
|
||||
stage: string;
|
||||
} | {
|
||||
type: 'inline' | 'external';
|
||||
value: string;
|
||||
})[];
|
||||
styles: StylesheetAsset[];
|
||||
}
|
||||
export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
|
||||
routeData: SerializedRouteData;
|
||||
};
|
||||
export type ImportComponentInstance = () => Promise<SinglePageBuiltModule>;
|
||||
export type AssetsPrefix = string | ({
|
||||
fallback: string;
|
||||
} & Record<string, string>) | undefined;
|
||||
export type SSRManifest = {
|
||||
hrefRoot: string;
|
||||
adapterName: string;
|
||||
routes: RouteInfo[];
|
||||
site?: string;
|
||||
base: string;
|
||||
trailingSlash: 'always' | 'never' | 'ignore';
|
||||
buildFormat: 'file' | 'directory' | 'preserve';
|
||||
compressHTML: boolean;
|
||||
assetsPrefix?: AssetsPrefix;
|
||||
renderers: SSRLoadedRenderer[];
|
||||
/**
|
||||
* Map of directive name (e.g. `load`) to the directive script code
|
||||
*/
|
||||
clientDirectives: Map<string, string>;
|
||||
entryModules: Record<string, string>;
|
||||
inlinedScripts: Map<string, string>;
|
||||
assets: Set<string>;
|
||||
componentMetadata: SSRResult['componentMetadata'];
|
||||
pageModule?: SinglePageBuiltModule;
|
||||
pageMap?: Map<ComponentPath, ImportComponentInstance>;
|
||||
serverIslandMap?: Map<string, () => Promise<ComponentInstance>>;
|
||||
serverIslandNameMap?: Map<string, string>;
|
||||
key: Promise<CryptoKey>;
|
||||
i18n: SSRManifestI18n | undefined;
|
||||
middleware?: () => Promise<AstroMiddlewareInstance> | AstroMiddlewareInstance;
|
||||
checkOrigin: boolean;
|
||||
experimentalEnvGetSecretEnabled: boolean;
|
||||
};
|
||||
export type SSRManifestI18n = {
|
||||
fallback: Record<string, string> | undefined;
|
||||
fallbackType: 'redirect' | 'rewrite';
|
||||
strategy: RoutingStrategies;
|
||||
locales: Locales;
|
||||
defaultLocale: string;
|
||||
domainLookupTable: Record<string, string>;
|
||||
};
|
||||
export type SerializedSSRManifest = Omit<SSRManifest, 'middleware' | 'routes' | 'assets' | 'componentMetadata' | 'inlinedScripts' | 'clientDirectives' | 'serverIslandNameMap' | 'key'> & {
|
||||
routes: SerializedRouteInfo[];
|
||||
assets: string[];
|
||||
componentMetadata: [string, SSRComponentMetadata][];
|
||||
inlinedScripts: [string, string][];
|
||||
clientDirectives: [string, string][];
|
||||
serverIslandNameMap: [string, string][];
|
||||
key: string;
|
||||
};
|
0
node_modules/astro/dist/core/app/types.js
generated
vendored
Normal file
0
node_modules/astro/dist/core/app/types.js
generated
vendored
Normal file
108
node_modules/astro/dist/core/base-pipeline.d.ts
generated
vendored
Normal file
108
node_modules/astro/dist/core/base-pipeline.d.ts
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
import type { ComponentInstance, MiddlewareHandler, RewritePayload, RouteData, RuntimeMode, SSRLoadedRenderer, SSRManifest, SSRResult } from '../@types/astro.js';
|
||||
import type { Logger } from './logger/core.js';
|
||||
import { RouteCache } from './render/route-cache.js';
|
||||
/**
|
||||
* The `Pipeline` represents the static parts of rendering that do not change between requests.
|
||||
* These are mostly known when the server first starts up and do not change.
|
||||
*
|
||||
* Thus, a `Pipeline` is created once at process start and then used by every `RenderContext`.
|
||||
*/
|
||||
export declare abstract class Pipeline {
|
||||
readonly logger: Logger;
|
||||
readonly manifest: SSRManifest;
|
||||
/**
|
||||
* "development" or "production"
|
||||
*/
|
||||
readonly mode: RuntimeMode;
|
||||
readonly renderers: SSRLoadedRenderer[];
|
||||
readonly resolve: (s: string) => Promise<string>;
|
||||
/**
|
||||
* Based on Astro config's `output` option, `true` if "server" or "hybrid".
|
||||
*/
|
||||
readonly serverLike: boolean;
|
||||
readonly streaming: boolean;
|
||||
/**
|
||||
* Used to provide better error messages for `Astro.clientAddress`
|
||||
*/
|
||||
readonly adapterName: string;
|
||||
readonly clientDirectives: Map<string, string>;
|
||||
readonly inlinedScripts: Map<string, string>;
|
||||
readonly compressHTML: boolean;
|
||||
readonly i18n: import("./app/types.js").SSRManifestI18n | undefined;
|
||||
readonly middleware: (() => Promise<import("../@types/astro.js").AstroMiddlewareInstance> | import("../@types/astro.js").AstroMiddlewareInstance) | undefined;
|
||||
readonly routeCache: RouteCache;
|
||||
/**
|
||||
* Used for `Astro.site`.
|
||||
*/
|
||||
readonly site: URL | undefined;
|
||||
/**
|
||||
* Array of built-in, internal, routes.
|
||||
* Used to find the route module
|
||||
*/
|
||||
readonly defaultRoutes: {
|
||||
instance: ComponentInstance;
|
||||
matchesComponent(filePath: URL): boolean;
|
||||
route: string;
|
||||
component: string;
|
||||
}[];
|
||||
readonly internalMiddleware: MiddlewareHandler[];
|
||||
resolvedMiddleware: MiddlewareHandler | undefined;
|
||||
constructor(logger: Logger, manifest: SSRManifest,
|
||||
/**
|
||||
* "development" or "production"
|
||||
*/
|
||||
mode: RuntimeMode, renderers: SSRLoadedRenderer[], resolve: (s: string) => Promise<string>,
|
||||
/**
|
||||
* Based on Astro config's `output` option, `true` if "server" or "hybrid".
|
||||
*/
|
||||
serverLike: boolean, streaming: boolean,
|
||||
/**
|
||||
* Used to provide better error messages for `Astro.clientAddress`
|
||||
*/
|
||||
adapterName?: string, clientDirectives?: Map<string, string>, inlinedScripts?: Map<string, string>, compressHTML?: boolean, i18n?: import("./app/types.js").SSRManifestI18n | undefined, middleware?: (() => Promise<import("../@types/astro.js").AstroMiddlewareInstance> | import("../@types/astro.js").AstroMiddlewareInstance) | undefined, routeCache?: RouteCache,
|
||||
/**
|
||||
* Used for `Astro.site`.
|
||||
*/
|
||||
site?: URL | undefined,
|
||||
/**
|
||||
* Array of built-in, internal, routes.
|
||||
* Used to find the route module
|
||||
*/
|
||||
defaultRoutes?: {
|
||||
instance: ComponentInstance;
|
||||
matchesComponent(filePath: URL): boolean;
|
||||
route: string;
|
||||
component: string;
|
||||
}[]);
|
||||
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
||||
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
||||
/**
|
||||
* It attempts to retrieve the `RouteData` that matches the input `url`, and the component that belongs to the `RouteData`.
|
||||
*
|
||||
* ## Errors
|
||||
*
|
||||
* - if not `RouteData` is found
|
||||
*
|
||||
* @param {RewritePayload} rewritePayload The payload provided by the user
|
||||
* @param {Request} request The original request
|
||||
*/
|
||||
abstract tryRewrite(rewritePayload: RewritePayload, request: Request): Promise<TryRewriteResult>;
|
||||
/**
|
||||
* Tells the pipeline how to retrieve a component give a `RouteData`
|
||||
* @param routeData
|
||||
*/
|
||||
abstract getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
||||
/**
|
||||
* Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
|
||||
* it returns a no-op function
|
||||
*/
|
||||
getMiddleware(): Promise<MiddlewareHandler>;
|
||||
}
|
||||
export interface HeadElements extends Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
||||
}
|
||||
export interface TryRewriteResult {
|
||||
routeData: RouteData;
|
||||
componentInstance: ComponentInstance;
|
||||
newUrl: URL;
|
||||
pathname: string;
|
||||
}
|
61
node_modules/astro/dist/core/base-pipeline.js
generated
vendored
Normal file
61
node_modules/astro/dist/core/base-pipeline.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { setGetEnv } from "../env/runtime.js";
|
||||
import { createI18nMiddleware } from "../i18n/middleware.js";
|
||||
import { createOriginCheckMiddleware } from "./app/middlewares.js";
|
||||
import { AstroError } from "./errors/errors.js";
|
||||
import { AstroErrorData } from "./errors/index.js";
|
||||
import { sequence } from "./middleware/index.js";
|
||||
import { NOOP_MIDDLEWARE_FN } from "./middleware/noop-middleware.js";
|
||||
import { RouteCache } from "./render/route-cache.js";
|
||||
import { createDefaultRoutes } from "./routing/default.js";
|
||||
class Pipeline {
|
||||
constructor(logger, manifest, mode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, mode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest)) {
|
||||
this.logger = logger;
|
||||
this.manifest = manifest;
|
||||
this.mode = mode;
|
||||
this.renderers = renderers;
|
||||
this.resolve = resolve;
|
||||
this.serverLike = serverLike;
|
||||
this.streaming = streaming;
|
||||
this.adapterName = adapterName;
|
||||
this.clientDirectives = clientDirectives;
|
||||
this.inlinedScripts = inlinedScripts;
|
||||
this.compressHTML = compressHTML;
|
||||
this.i18n = i18n;
|
||||
this.middleware = middleware;
|
||||
this.routeCache = routeCache;
|
||||
this.site = site;
|
||||
this.defaultRoutes = defaultRoutes;
|
||||
this.internalMiddleware = [];
|
||||
if (i18n?.strategy !== "manual") {
|
||||
this.internalMiddleware.push(
|
||||
createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat)
|
||||
);
|
||||
}
|
||||
}
|
||||
internalMiddleware;
|
||||
resolvedMiddleware = void 0;
|
||||
/**
|
||||
* Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
|
||||
* it returns a no-op function
|
||||
*/
|
||||
async getMiddleware() {
|
||||
if (this.resolvedMiddleware) {
|
||||
return this.resolvedMiddleware;
|
||||
} else if (this.middleware) {
|
||||
const middlewareInstance = await this.middleware();
|
||||
const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN;
|
||||
if (this.manifest.checkOrigin) {
|
||||
this.resolvedMiddleware = sequence(createOriginCheckMiddleware(), onRequest);
|
||||
} else {
|
||||
this.resolvedMiddleware = onRequest;
|
||||
}
|
||||
return this.resolvedMiddleware;
|
||||
} else {
|
||||
this.resolvedMiddleware = NOOP_MIDDLEWARE_FN;
|
||||
return this.resolvedMiddleware;
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
Pipeline
|
||||
};
|
2
node_modules/astro/dist/core/build/add-rollup-input.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/build/add-rollup-input.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { Rollup } from 'vite';
|
||||
export declare function addRollupInput(inputOptions: Rollup.InputOptions, newInputs: string[]): Rollup.InputOptions;
|
37
node_modules/astro/dist/core/build/add-rollup-input.js
generated
vendored
Normal file
37
node_modules/astro/dist/core/build/add-rollup-input.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
function fromEntries(entries) {
|
||||
const obj = {};
|
||||
for (const [k, v] of entries) {
|
||||
obj[k] = v;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
function addRollupInput(inputOptions, newInputs) {
|
||||
if (!inputOptions.input) {
|
||||
return { ...inputOptions, input: newInputs };
|
||||
}
|
||||
if (typeof inputOptions.input === "string") {
|
||||
return {
|
||||
...inputOptions,
|
||||
input: [inputOptions.input, ...newInputs]
|
||||
};
|
||||
}
|
||||
if (Array.isArray(inputOptions.input)) {
|
||||
return {
|
||||
...inputOptions,
|
||||
input: [...inputOptions.input, ...newInputs]
|
||||
};
|
||||
}
|
||||
if (typeof inputOptions.input === "object") {
|
||||
return {
|
||||
...inputOptions,
|
||||
input: {
|
||||
...inputOptions.input,
|
||||
...fromEntries(newInputs.map((i) => [i.split("/").slice(-1)[0].split(".")[0], i]))
|
||||
}
|
||||
};
|
||||
}
|
||||
throw new Error(`Unknown rollup input type. Supported inputs are string, array and object.`);
|
||||
}
|
||||
export {
|
||||
addRollupInput
|
||||
};
|
9
node_modules/astro/dist/core/build/common.d.ts
generated
vendored
Normal file
9
node_modules/astro/dist/core/build/common.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { AstroConfig, RouteData } from '../../@types/astro.js';
|
||||
export declare function getOutFolder(astroConfig: AstroConfig, pathname: string, routeData: RouteData): URL;
|
||||
export declare function getOutFile(astroConfig: AstroConfig, outFolder: URL, pathname: string, routeData: RouteData): URL;
|
||||
/**
|
||||
* Ensures the `outDir` is within `process.cwd()`. If not it will fallback to `<cwd>/.astro`.
|
||||
* This is used for static `ssrBuild` so the output can access node_modules when we import
|
||||
* the output files. A hardcoded fallback dir is fine as it would be cleaned up after build.
|
||||
*/
|
||||
export declare function getOutDirWithinCwd(outDir: URL): URL;
|
86
node_modules/astro/dist/core/build/common.js
generated
vendored
Normal file
86
node_modules/astro/dist/core/build/common.js
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
import npath from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { appendForwardSlash } from "../../core/path.js";
|
||||
const STATUS_CODE_PAGES = /* @__PURE__ */ new Set(["/404", "/500"]);
|
||||
const FALLBACK_OUT_DIR_NAME = "./.astro/";
|
||||
function getOutRoot(astroConfig) {
|
||||
if (astroConfig.output === "static") {
|
||||
return new URL("./", astroConfig.outDir);
|
||||
} else {
|
||||
return new URL("./", astroConfig.build.client);
|
||||
}
|
||||
}
|
||||
function getOutFolder(astroConfig, pathname, routeData) {
|
||||
const outRoot = getOutRoot(astroConfig);
|
||||
const routeType = routeData.type;
|
||||
switch (routeType) {
|
||||
case "endpoint":
|
||||
return new URL("." + appendForwardSlash(npath.dirname(pathname)), outRoot);
|
||||
case "fallback":
|
||||
case "page":
|
||||
case "redirect":
|
||||
switch (astroConfig.build.format) {
|
||||
case "directory": {
|
||||
if (STATUS_CODE_PAGES.has(pathname)) {
|
||||
return new URL("." + appendForwardSlash(npath.dirname(pathname)), outRoot);
|
||||
}
|
||||
return new URL("." + appendForwardSlash(pathname), outRoot);
|
||||
}
|
||||
case "file": {
|
||||
const d = pathname === "" ? pathname : npath.dirname(pathname);
|
||||
return new URL("." + appendForwardSlash(d), outRoot);
|
||||
}
|
||||
case "preserve": {
|
||||
let dir;
|
||||
if (pathname === "" || routeData.isIndex) {
|
||||
dir = pathname;
|
||||
} else {
|
||||
dir = npath.dirname(pathname);
|
||||
}
|
||||
return new URL("." + appendForwardSlash(dir), outRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function getOutFile(astroConfig, outFolder, pathname, routeData) {
|
||||
const routeType = routeData.type;
|
||||
switch (routeType) {
|
||||
case "endpoint":
|
||||
return new URL(npath.basename(pathname), outFolder);
|
||||
case "page":
|
||||
case "fallback":
|
||||
case "redirect":
|
||||
switch (astroConfig.build.format) {
|
||||
case "directory": {
|
||||
if (STATUS_CODE_PAGES.has(pathname)) {
|
||||
const baseName = npath.basename(pathname);
|
||||
return new URL("./" + (baseName || "index") + ".html", outFolder);
|
||||
}
|
||||
return new URL("./index.html", outFolder);
|
||||
}
|
||||
case "file": {
|
||||
const baseName = npath.basename(pathname);
|
||||
return new URL("./" + (baseName || "index") + ".html", outFolder);
|
||||
}
|
||||
case "preserve": {
|
||||
let baseName = npath.basename(pathname);
|
||||
if (!baseName || routeData.isIndex) {
|
||||
baseName = "index";
|
||||
}
|
||||
return new URL(`./${baseName}.html`, outFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function getOutDirWithinCwd(outDir) {
|
||||
if (fileURLToPath(outDir).startsWith(process.cwd())) {
|
||||
return outDir;
|
||||
} else {
|
||||
return new URL(FALLBACK_OUT_DIR_NAME, pathToFileURL(process.cwd() + npath.sep));
|
||||
}
|
||||
}
|
||||
export {
|
||||
getOutDirWithinCwd,
|
||||
getOutFile,
|
||||
getOutFolder
|
||||
};
|
2
node_modules/astro/dist/core/build/consts.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/build/consts.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export declare const CHUNKS_PATH = "chunks/";
|
||||
export declare const CONTENT_PATH = "content/";
|
6
node_modules/astro/dist/core/build/consts.js
generated
vendored
Normal file
6
node_modules/astro/dist/core/build/consts.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
const CHUNKS_PATH = "chunks/";
|
||||
const CONTENT_PATH = "content/";
|
||||
export {
|
||||
CHUNKS_PATH,
|
||||
CONTENT_PATH
|
||||
};
|
9
node_modules/astro/dist/core/build/css-asset-name.d.ts
generated
vendored
Normal file
9
node_modules/astro/dist/core/build/css-asset-name.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { GetModuleInfo } from 'rollup';
|
||||
import type { AstroSettings } from '../../@types/astro.js';
|
||||
export declare function shortHashedName(settings: AstroSettings): (id: string, ctx: {
|
||||
getModuleInfo: GetModuleInfo;
|
||||
}) => string;
|
||||
export declare function createNameHash(baseId: string | undefined, hashIds: string[], settings: AstroSettings): string;
|
||||
export declare function createSlugger(settings: AstroSettings): (id: string, ctx: {
|
||||
getModuleInfo: GetModuleInfo;
|
||||
}) => string;
|
89
node_modules/astro/dist/core/build/css-asset-name.js
generated
vendored
Normal file
89
node_modules/astro/dist/core/build/css-asset-name.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import crypto from "node:crypto";
|
||||
import npath from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { normalizePath } from "vite";
|
||||
import { viteID } from "../util.js";
|
||||
import { getTopLevelPageModuleInfos } from "./graph.js";
|
||||
const confusingBaseNames = ["404", "500"];
|
||||
function shortHashedName(settings) {
|
||||
return function(id, ctx) {
|
||||
const parents = getTopLevelPageModuleInfos(id, ctx);
|
||||
return createNameHash(
|
||||
getFirstParentId(parents),
|
||||
parents.map((page) => page.id),
|
||||
settings
|
||||
);
|
||||
};
|
||||
}
|
||||
function createNameHash(baseId, hashIds, settings) {
|
||||
const baseName = baseId ? prettifyBaseName(npath.parse(baseId).name) : "index";
|
||||
const hash = crypto.createHash("sha256");
|
||||
const root = fileURLToPath(settings.config.root);
|
||||
for (const id of hashIds) {
|
||||
const relativePath = npath.relative(root, id);
|
||||
hash.update(normalizePath(relativePath), "utf-8");
|
||||
}
|
||||
const h = hash.digest("hex").slice(0, 8);
|
||||
const proposedName = baseName + "." + h;
|
||||
return proposedName;
|
||||
}
|
||||
function createSlugger(settings) {
|
||||
const pagesDir = viteID(new URL("./pages", settings.config.srcDir));
|
||||
const indexPage = viteID(new URL("./pages/index", settings.config.srcDir));
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
const sep = "-";
|
||||
return function(id, ctx) {
|
||||
const parents = Array.from(getTopLevelPageModuleInfos(id, ctx));
|
||||
const allParentsKey = parents.map((page) => page.id).sort().join("-");
|
||||
const firstParentId = getFirstParentId(parents) || indexPage;
|
||||
let dir = firstParentId;
|
||||
let key = "";
|
||||
let i = 0;
|
||||
while (i < 2) {
|
||||
if (dir === pagesDir) {
|
||||
break;
|
||||
}
|
||||
const name2 = prettifyBaseName(npath.parse(npath.basename(dir)).name);
|
||||
key = key.length ? name2 + sep + key : name2;
|
||||
dir = npath.dirname(dir);
|
||||
i++;
|
||||
}
|
||||
let name = key;
|
||||
if (!map.has(key)) {
|
||||
map.set(key, /* @__PURE__ */ new Map([[allParentsKey, 0]]));
|
||||
} else {
|
||||
const inner = map.get(key);
|
||||
if (inner.has(allParentsKey)) {
|
||||
const num = inner.get(allParentsKey);
|
||||
if (num > 0) {
|
||||
name = name + sep + num;
|
||||
}
|
||||
} else {
|
||||
const num = inner.size;
|
||||
inner.set(allParentsKey, num);
|
||||
name = name + sep + num;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
};
|
||||
}
|
||||
function getFirstParentId(parents) {
|
||||
for (const parent of parents) {
|
||||
const id = parent.id;
|
||||
const baseName = npath.parse(id).name;
|
||||
if (!confusingBaseNames.includes(baseName)) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return parents[0]?.id;
|
||||
}
|
||||
const charsToReplaceRe = /[.[\]]/g;
|
||||
const underscoresRe = /_+/g;
|
||||
function prettifyBaseName(str) {
|
||||
return str.replace(charsToReplaceRe, "_").replace(underscoresRe, "_");
|
||||
}
|
||||
export {
|
||||
createNameHash,
|
||||
createSlugger,
|
||||
shortHashedName
|
||||
};
|
3
node_modules/astro/dist/core/build/generate.d.ts
generated
vendored
Normal file
3
node_modules/astro/dist/core/build/generate.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { type BuildInternals } from '../../core/build/internal.js';
|
||||
import type { StaticBuildOptions } from './types.js';
|
||||
export declare function generatePages(options: StaticBuildOptions, internals: BuildInternals): Promise<void>;
|
416
node_modules/astro/dist/core/build/generate.js
generated
vendored
Normal file
416
node_modules/astro/dist/core/build/generate.js
generated
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import { bgGreen, black, blue, bold, dim, green, magenta, red } from "kleur/colors";
|
||||
import PLimit from "p-limit";
|
||||
import PQueue from "p-queue";
|
||||
import {
|
||||
generateImagesForPath,
|
||||
getStaticImageList,
|
||||
prepareAssetsGenerationEnv
|
||||
} from "../../assets/build/generate.js";
|
||||
import { hasPrerenderedPages } from "../../core/build/internal.js";
|
||||
import {
|
||||
isRelativePath,
|
||||
joinPaths,
|
||||
removeLeadingForwardSlash,
|
||||
removeTrailingForwardSlash
|
||||
} from "../../core/path.js";
|
||||
import { toFallbackType, toRoutingStrategy } from "../../i18n/utils.js";
|
||||
import { runHookBuildGenerated } from "../../integrations/hooks.js";
|
||||
import { getOutputDirectory } from "../../prerender/utils.js";
|
||||
import { NoPrerenderedRoutesWithDomains } from "../errors/errors-data.js";
|
||||
import { AstroError, AstroErrorData } from "../errors/index.js";
|
||||
import { NOOP_MIDDLEWARE_FN } from "../middleware/noop-middleware.js";
|
||||
import { getRedirectLocationOrThrow, routeIsRedirect } from "../redirects/index.js";
|
||||
import { RenderContext } from "../render-context.js";
|
||||
import { callGetStaticPaths } from "../render/route-cache.js";
|
||||
import { createRequest } from "../request.js";
|
||||
import { matchRoute } from "../routing/match.js";
|
||||
import { stringifyParams } from "../routing/params.js";
|
||||
import { getOutputFilename, isServerLikeOutput } from "../util.js";
|
||||
import { getOutDirWithinCwd, getOutFile, getOutFolder } from "./common.js";
|
||||
import { cssOrder, mergeInlineCss } from "./internal.js";
|
||||
import { BuildPipeline } from "./pipeline.js";
|
||||
import { getTimeStat, shouldAppendForwardSlash } from "./util.js";
|
||||
function createEntryURL(filePath, outFolder) {
|
||||
return new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
|
||||
}
|
||||
async function generatePages(options, internals) {
|
||||
const generatePagesTimer = performance.now();
|
||||
const ssr = isServerLikeOutput(options.settings.config);
|
||||
let manifest;
|
||||
if (ssr) {
|
||||
manifest = await BuildPipeline.retrieveManifest(options, internals);
|
||||
} else {
|
||||
const baseDirectory = getOutputDirectory(options.settings.config);
|
||||
const renderersEntryUrl = new URL("renderers.mjs", baseDirectory);
|
||||
const renderers = await import(renderersEntryUrl.toString());
|
||||
const middleware = internals.middlewareEntryPoint ? await import(internals.middlewareEntryPoint.toString()).then((mod) => mod.onRequest) : NOOP_MIDDLEWARE_FN;
|
||||
manifest = createBuildManifest(
|
||||
options.settings,
|
||||
internals,
|
||||
renderers.renderers,
|
||||
middleware,
|
||||
options.key
|
||||
);
|
||||
}
|
||||
const pipeline = BuildPipeline.create({ internals, manifest, options });
|
||||
const { config, logger } = pipeline;
|
||||
const outFolder = ssr ? options.settings.config.build.server : getOutDirWithinCwd(options.settings.config.outDir);
|
||||
if (ssr && !hasPrerenderedPages(internals)) {
|
||||
delete globalThis?.astroAsset?.addStaticImage;
|
||||
return;
|
||||
}
|
||||
const verb = ssr ? "prerendering" : "generating";
|
||||
logger.info("SKIP_FORMAT", `
|
||||
${bgGreen(black(` ${verb} static routes `))}`);
|
||||
const builtPaths = /* @__PURE__ */ new Set();
|
||||
const pagesToGenerate = pipeline.retrieveRoutesToGenerate();
|
||||
if (ssr) {
|
||||
for (const [pageData, filePath] of pagesToGenerate) {
|
||||
if (pageData.route.prerender) {
|
||||
if (config.i18n?.domains && Object.keys(config.i18n.domains).length > 0) {
|
||||
throw new AstroError({
|
||||
...NoPrerenderedRoutesWithDomains,
|
||||
message: NoPrerenderedRoutesWithDomains.message(pageData.component)
|
||||
});
|
||||
}
|
||||
const ssrEntryPage = await pipeline.retrieveSsrEntry(pageData.route, filePath);
|
||||
if (options.settings.adapter?.adapterFeatures?.functionPerRoute) {
|
||||
const ssrEntry = ssrEntryPage?.pageModule;
|
||||
if (ssrEntry) {
|
||||
await generatePage(pageData, ssrEntry, builtPaths, pipeline);
|
||||
} else {
|
||||
const ssrEntryURLPage = createEntryURL(filePath, outFolder);
|
||||
throw new Error(
|
||||
`Unable to find the manifest for the module ${ssrEntryURLPage.toString()}. This is unexpected and likely a bug in Astro, please report.`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const ssrEntry = ssrEntryPage;
|
||||
await generatePage(pageData, ssrEntry, builtPaths, pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const [pageData, filePath] of pagesToGenerate) {
|
||||
const entry = await pipeline.retrieveSsrEntry(pageData.route, filePath);
|
||||
await generatePage(pageData, entry, builtPaths, pipeline);
|
||||
}
|
||||
}
|
||||
logger.info(
|
||||
null,
|
||||
green(`\u2713 Completed in ${getTimeStat(generatePagesTimer, performance.now())}.
|
||||
`)
|
||||
);
|
||||
const staticImageList = getStaticImageList();
|
||||
if (staticImageList.size) {
|
||||
logger.info("SKIP_FORMAT", `${bgGreen(black(` generating optimized images `))}`);
|
||||
const totalCount = Array.from(staticImageList.values()).map((x) => x.transforms.size).reduce((a, b) => a + b, 0);
|
||||
const cpuCount = os.cpus().length;
|
||||
const assetsCreationPipeline = await prepareAssetsGenerationEnv(pipeline, totalCount);
|
||||
const queue = new PQueue({ concurrency: Math.max(cpuCount, 1) });
|
||||
const assetsTimer = performance.now();
|
||||
for (const [originalPath, transforms] of staticImageList) {
|
||||
await generateImagesForPath(originalPath, transforms, assetsCreationPipeline, queue);
|
||||
}
|
||||
await queue.onIdle();
|
||||
const assetsTimeEnd = performance.now();
|
||||
logger.info(null, green(`\u2713 Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.
|
||||
`));
|
||||
delete globalThis?.astroAsset?.addStaticImage;
|
||||
}
|
||||
await runHookBuildGenerated({ config, logger });
|
||||
}
|
||||
const THRESHOLD_SLOW_RENDER_TIME_MS = 500;
|
||||
async function generatePage(pageData, ssrEntry, builtPaths, pipeline) {
|
||||
const { config, logger } = pipeline;
|
||||
const pageModulePromise = ssrEntry.page;
|
||||
const styles = pageData.styles.sort(cssOrder).map(({ sheet }) => sheet).reduce(mergeInlineCss, []);
|
||||
const linkIds = [];
|
||||
const scripts = pageData.hoistedScript ?? null;
|
||||
if (!pageModulePromise) {
|
||||
throw new Error(
|
||||
`Unable to find the module for ${pageData.component}. This is unexpected and likely a bug in Astro, please report.`
|
||||
);
|
||||
}
|
||||
const pageModule = await pageModulePromise();
|
||||
const generationOptions = {
|
||||
pageData,
|
||||
linkIds,
|
||||
scripts,
|
||||
styles,
|
||||
mod: pageModule
|
||||
};
|
||||
async function generatePathWithLogs(path, route, index, paths, isConcurrent) {
|
||||
const timeStart = performance.now();
|
||||
pipeline.logger.debug("build", `Generating: ${path}`);
|
||||
const filePath = getOutputFilename(config, path, pageData.route.type);
|
||||
const lineIcon = index === paths.length - 1 && !isConcurrent || paths.length === 1 ? "\u2514\u2500" : "\u251C\u2500";
|
||||
if (!isConcurrent) {
|
||||
logger.info(null, ` ${blue(lineIcon)} ${dim(filePath)}`, false);
|
||||
}
|
||||
await generatePath(path, pipeline, generationOptions, route);
|
||||
const timeEnd = performance.now();
|
||||
const isSlow = timeEnd - timeStart > THRESHOLD_SLOW_RENDER_TIME_MS;
|
||||
const timeIncrease = (isSlow ? red : dim)(`(+${getTimeStat(timeStart, timeEnd)})`);
|
||||
if (isConcurrent) {
|
||||
logger.info(null, ` ${blue(lineIcon)} ${dim(filePath)} ${timeIncrease}`);
|
||||
} else {
|
||||
logger.info("SKIP_FORMAT", ` ${timeIncrease}`);
|
||||
}
|
||||
}
|
||||
for (const route of eachRouteInRouteData(pageData)) {
|
||||
const icon = route.type === "page" || route.type === "redirect" || route.type === "fallback" ? green("\u25B6") : magenta("\u03BB");
|
||||
logger.info(null, `${icon} ${getPrettyRouteName(route)}`);
|
||||
const paths = await getPathsForRoute(route, pageModule, pipeline, builtPaths);
|
||||
if (config.build.concurrency > 1) {
|
||||
const limit = PLimit(config.build.concurrency);
|
||||
const promises = [];
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const path = paths[i];
|
||||
promises.push(limit(() => generatePathWithLogs(path, route, i, paths, true)));
|
||||
}
|
||||
await Promise.allSettled(promises);
|
||||
} else {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const path = paths[i];
|
||||
await generatePathWithLogs(path, route, i, paths, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function* eachRouteInRouteData(data) {
|
||||
yield data.route;
|
||||
for (const fallbackRoute of data.route.fallbackRoutes) {
|
||||
yield fallbackRoute;
|
||||
}
|
||||
}
|
||||
async function getPathsForRoute(route, mod, pipeline, builtPaths) {
|
||||
const { logger, options, routeCache, serverLike } = pipeline;
|
||||
let paths = [];
|
||||
if (route.pathname) {
|
||||
paths.push(route.pathname);
|
||||
builtPaths.add(removeTrailingForwardSlash(route.pathname));
|
||||
} else {
|
||||
const staticPaths = await callGetStaticPaths({
|
||||
mod,
|
||||
route,
|
||||
routeCache,
|
||||
logger,
|
||||
ssr: serverLike
|
||||
}).catch((err) => {
|
||||
logger.error("build", `Failed to call getStaticPaths for ${route.component}`);
|
||||
throw err;
|
||||
});
|
||||
const label = staticPaths.length === 1 ? "page" : "pages";
|
||||
logger.debug(
|
||||
"build",
|
||||
`\u251C\u2500\u2500 ${bold(green("\u221A"))} ${route.component} \u2192 ${magenta(`[${staticPaths.length} ${label}]`)}`
|
||||
);
|
||||
paths = staticPaths.map((staticPath) => {
|
||||
try {
|
||||
return stringifyParams(staticPath.params, route);
|
||||
} catch (e) {
|
||||
if (e instanceof TypeError) {
|
||||
throw getInvalidRouteSegmentError(e, route, staticPath);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}).filter((staticPath) => {
|
||||
if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
|
||||
return true;
|
||||
}
|
||||
const matchedRoute = matchRoute(staticPath, options.manifest);
|
||||
return matchedRoute === route;
|
||||
});
|
||||
for (const staticPath of paths) {
|
||||
builtPaths.add(removeTrailingForwardSlash(staticPath));
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
function getInvalidRouteSegmentError(e, route, staticPath) {
|
||||
const invalidParam = /^Expected "([^"]+)"/.exec(e.message)?.[1];
|
||||
const received = invalidParam ? staticPath.params[invalidParam] : void 0;
|
||||
let hint = "Learn about dynamic routes at https://docs.astro.build/en/core-concepts/routing/#dynamic-routes";
|
||||
if (invalidParam && typeof received === "string") {
|
||||
const matchingSegment = route.segments.find(
|
||||
(segment) => segment[0]?.content === invalidParam
|
||||
)?.[0];
|
||||
const mightBeMissingSpread = matchingSegment?.dynamic && !matchingSegment?.spread;
|
||||
if (mightBeMissingSpread) {
|
||||
hint = `If the param contains slashes, try using a rest parameter: **[...${invalidParam}]**. Learn more at https://docs.astro.build/en/core-concepts/routing/#dynamic-routes`;
|
||||
}
|
||||
}
|
||||
return new AstroError({
|
||||
...AstroErrorData.InvalidDynamicRoute,
|
||||
message: invalidParam ? AstroErrorData.InvalidDynamicRoute.message(
|
||||
route.route,
|
||||
JSON.stringify(invalidParam),
|
||||
JSON.stringify(received)
|
||||
) : `Generated path for ${route.route} is invalid.`,
|
||||
hint
|
||||
});
|
||||
}
|
||||
function addPageName(pathname, opts) {
|
||||
const trailingSlash = opts.settings.config.trailingSlash;
|
||||
const buildFormat = opts.settings.config.build.format;
|
||||
const pageName = shouldAppendForwardSlash(trailingSlash, buildFormat) ? pathname.replace(/\/?$/, "/").replace(/^\//, "") : pathname.replace(/^\//, "");
|
||||
opts.pageNames.push(pageName);
|
||||
}
|
||||
function getUrlForPath(pathname, base, origin, format, trailingSlash, routeType) {
|
||||
let ending;
|
||||
switch (format) {
|
||||
case "directory":
|
||||
case "preserve": {
|
||||
ending = trailingSlash === "never" ? "" : "/";
|
||||
break;
|
||||
}
|
||||
case "file":
|
||||
default: {
|
||||
ending = ".html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
let buildPathname;
|
||||
if (pathname === "/" || pathname === "") {
|
||||
buildPathname = base;
|
||||
} else if (routeType === "endpoint") {
|
||||
const buildPathRelative = removeLeadingForwardSlash(pathname);
|
||||
buildPathname = joinPaths(base, buildPathRelative);
|
||||
} else {
|
||||
const buildPathRelative = removeTrailingForwardSlash(removeLeadingForwardSlash(pathname)) + ending;
|
||||
buildPathname = joinPaths(base, buildPathRelative);
|
||||
}
|
||||
const url = new URL(buildPathname, origin);
|
||||
return url;
|
||||
}
|
||||
async function generatePath(pathname, pipeline, gopts, route) {
|
||||
const { mod } = gopts;
|
||||
const { config, logger, options } = pipeline;
|
||||
logger.debug("build", `Generating: ${pathname}`);
|
||||
if (route.type === "page") {
|
||||
addPageName(pathname, options);
|
||||
}
|
||||
if (route.type === "fallback" && // If route is index page, continue rendering. The index page should
|
||||
// always be rendered
|
||||
route.pathname !== "/" && // Check if there is a translated page with the same path
|
||||
Object.values(options.allPages).some((val) => val.route.pattern.test(pathname))) {
|
||||
return;
|
||||
}
|
||||
const url = getUrlForPath(
|
||||
pathname,
|
||||
config.base,
|
||||
options.origin,
|
||||
config.build.format,
|
||||
config.trailingSlash,
|
||||
route.type
|
||||
);
|
||||
const request = createRequest({
|
||||
base: config.base,
|
||||
url,
|
||||
headers: new Headers(),
|
||||
logger,
|
||||
staticLike: true
|
||||
});
|
||||
const renderContext = await RenderContext.create({
|
||||
pipeline,
|
||||
pathname,
|
||||
request,
|
||||
routeData: route
|
||||
});
|
||||
let body;
|
||||
let response;
|
||||
try {
|
||||
response = await renderContext.render(mod);
|
||||
} catch (err) {
|
||||
if (!AstroError.is(err) && !err.id && typeof err === "object") {
|
||||
err.id = route.component;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
if (response.status >= 300 && response.status < 400) {
|
||||
if (routeIsRedirect(route) && !config.build.redirects) {
|
||||
return;
|
||||
}
|
||||
const locationSite = getRedirectLocationOrThrow(response.headers);
|
||||
const siteURL = config.site;
|
||||
const location = siteURL ? new URL(locationSite, siteURL) : locationSite;
|
||||
const fromPath = new URL(request.url).pathname;
|
||||
const delay = response.status === 302 ? 2 : 0;
|
||||
body = `<!doctype html>
|
||||
<title>Redirecting to: ${location}</title>
|
||||
<meta http-equiv="refresh" content="${delay};url=${location}">
|
||||
<meta name="robots" content="noindex">
|
||||
<link rel="canonical" href="${location}">
|
||||
<body>
|
||||
<a href="${location}">Redirecting from <code>${fromPath}</code> to <code>${location}</code></a>
|
||||
</body>`;
|
||||
if (config.compressHTML === true) {
|
||||
body = body.replaceAll("\n", "");
|
||||
}
|
||||
if (route.type !== "redirect") {
|
||||
route.redirect = location.toString();
|
||||
}
|
||||
} else {
|
||||
if (!response.body) return;
|
||||
body = Buffer.from(await response.arrayBuffer());
|
||||
}
|
||||
const outFolder = getOutFolder(config, pathname, route);
|
||||
const outFile = getOutFile(config, outFolder, pathname, route);
|
||||
route.distURL = outFile;
|
||||
await fs.promises.mkdir(outFolder, { recursive: true });
|
||||
await fs.promises.writeFile(outFile, body);
|
||||
}
|
||||
function getPrettyRouteName(route) {
|
||||
if (isRelativePath(route.component)) {
|
||||
return route.route;
|
||||
} else if (route.component.includes("node_modules/")) {
|
||||
return /.*node_modules\/(.+)/.exec(route.component)?.[1] ?? route.component;
|
||||
} else {
|
||||
return route.component;
|
||||
}
|
||||
}
|
||||
function createBuildManifest(settings, internals, renderers, middleware, key) {
|
||||
let i18nManifest = void 0;
|
||||
if (settings.config.i18n) {
|
||||
i18nManifest = {
|
||||
fallback: settings.config.i18n.fallback,
|
||||
fallbackType: toFallbackType(settings.config.i18n.routing),
|
||||
strategy: toRoutingStrategy(settings.config.i18n.routing, settings.config.i18n.domains),
|
||||
defaultLocale: settings.config.i18n.defaultLocale,
|
||||
locales: settings.config.i18n.locales,
|
||||
domainLookupTable: {}
|
||||
};
|
||||
}
|
||||
return {
|
||||
hrefRoot: settings.config.root.toString(),
|
||||
trailingSlash: settings.config.trailingSlash,
|
||||
assets: /* @__PURE__ */ new Set(),
|
||||
entryModules: Object.fromEntries(internals.entrySpecifierToBundleMap.entries()),
|
||||
inlinedScripts: internals.inlinedScripts,
|
||||
routes: [],
|
||||
adapterName: "",
|
||||
clientDirectives: settings.clientDirectives,
|
||||
compressHTML: settings.config.compressHTML,
|
||||
renderers,
|
||||
base: settings.config.base,
|
||||
assetsPrefix: settings.config.build.assetsPrefix,
|
||||
site: settings.config.site,
|
||||
componentMetadata: internals.componentMetadata,
|
||||
i18n: i18nManifest,
|
||||
buildFormat: settings.config.build.format,
|
||||
middleware() {
|
||||
return {
|
||||
onRequest: middleware
|
||||
};
|
||||
},
|
||||
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
||||
key,
|
||||
experimentalEnvGetSecretEnabled: false
|
||||
};
|
||||
}
|
||||
export {
|
||||
generatePages
|
||||
};
|
17
node_modules/astro/dist/core/build/graph.d.ts
generated
vendored
Normal file
17
node_modules/astro/dist/core/build/graph.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { GetModuleInfo, ModuleInfo } from 'rollup';
|
||||
interface ExtendedModuleInfo {
|
||||
info: ModuleInfo;
|
||||
depth: number;
|
||||
order: number;
|
||||
}
|
||||
export declare function getParentExtendedModuleInfos(id: string, ctx: {
|
||||
getModuleInfo: GetModuleInfo;
|
||||
}, until?: (importer: string) => boolean, depth?: number, order?: number, childId?: string, seen?: Set<string>, accumulated?: ExtendedModuleInfo[]): ExtendedModuleInfo[];
|
||||
export declare function getParentModuleInfos(id: string, ctx: {
|
||||
getModuleInfo: GetModuleInfo;
|
||||
}, until?: (importer: string) => boolean, seen?: Set<string>, accumulated?: ModuleInfo[]): ModuleInfo[];
|
||||
export declare function moduleIsTopLevelPage(info: ModuleInfo): boolean;
|
||||
export declare function getTopLevelPageModuleInfos(id: string, ctx: {
|
||||
getModuleInfo: GetModuleInfo;
|
||||
}): ModuleInfo[];
|
||||
export {};
|
54
node_modules/astro/dist/core/build/graph.js
generated
vendored
Normal file
54
node_modules/astro/dist/core/build/graph.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
|
||||
function getParentExtendedModuleInfos(id, ctx, until, depth = 0, order = 0, childId = "", seen = /* @__PURE__ */ new Set(), accumulated = []) {
|
||||
seen.add(id);
|
||||
const info = ctx.getModuleInfo(id);
|
||||
if (info) {
|
||||
if (childId) {
|
||||
const idx = info.importedIds.indexOf(childId);
|
||||
if (idx === -1) {
|
||||
order += info.importedIds.length;
|
||||
order += info.dynamicallyImportedIds.indexOf(childId);
|
||||
} else {
|
||||
order += idx;
|
||||
}
|
||||
}
|
||||
accumulated.push({ info, depth, order });
|
||||
}
|
||||
if (info && !until?.(id)) {
|
||||
const importers = info.importers.concat(info.dynamicImporters);
|
||||
for (const imp of importers) {
|
||||
if (!seen.has(imp)) {
|
||||
getParentExtendedModuleInfos(imp, ctx, until, depth + 1, order, id, seen, accumulated);
|
||||
}
|
||||
}
|
||||
}
|
||||
return accumulated;
|
||||
}
|
||||
function getParentModuleInfos(id, ctx, until, seen = /* @__PURE__ */ new Set(), accumulated = []) {
|
||||
seen.add(id);
|
||||
const info = ctx.getModuleInfo(id);
|
||||
if (info) {
|
||||
accumulated.push(info);
|
||||
}
|
||||
if (info && !until?.(id)) {
|
||||
const importers = info.importers.concat(info.dynamicImporters);
|
||||
for (const imp of importers) {
|
||||
if (!seen.has(imp)) {
|
||||
getParentModuleInfos(imp, ctx, until, seen, accumulated);
|
||||
}
|
||||
}
|
||||
}
|
||||
return accumulated;
|
||||
}
|
||||
function moduleIsTopLevelPage(info) {
|
||||
return info.importers[0]?.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || info.dynamicImporters[0]?.includes(ASTRO_PAGE_RESOLVED_MODULE_ID);
|
||||
}
|
||||
function getTopLevelPageModuleInfos(id, ctx) {
|
||||
return getParentModuleInfos(id, ctx).filter(moduleIsTopLevelPage);
|
||||
}
|
||||
export {
|
||||
getParentExtendedModuleInfos,
|
||||
getParentModuleInfos,
|
||||
getTopLevelPageModuleInfos,
|
||||
moduleIsTopLevelPage
|
||||
};
|
10
node_modules/astro/dist/core/build/index.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/core/build/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { AstroInlineConfig } from '../../@types/astro.js';
|
||||
export interface BuildOptions {
|
||||
}
|
||||
/**
|
||||
* Builds your site for deployment. By default, this will generate static files and place them in a dist/ directory.
|
||||
* If SSR is enabled, this will generate the necessary server files to serve your site.
|
||||
*
|
||||
* @experimental The JavaScript API is experimental
|
||||
*/
|
||||
export default function build(inlineConfig: AstroInlineConfig, options?: BuildOptions): Promise<void>;
|
218
node_modules/astro/dist/core/build/index.js
generated
vendored
Normal file
218
node_modules/astro/dist/core/build/index.js
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
import fs from "node:fs";
|
||||
import { performance } from "node:perf_hooks";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { blue, bold, green } from "kleur/colors";
|
||||
import { injectImageEndpoint } from "../../assets/endpoint/config.js";
|
||||
import { telemetry } from "../../events/index.js";
|
||||
import { eventCliSession } from "../../events/session.js";
|
||||
import {
|
||||
runHookBuildDone,
|
||||
runHookBuildStart,
|
||||
runHookConfigDone,
|
||||
runHookConfigSetup
|
||||
} from "../../integrations/hooks.js";
|
||||
import { resolveConfig } from "../config/config.js";
|
||||
import { createNodeLogger } from "../config/logging.js";
|
||||
import { createSettings } from "../config/settings.js";
|
||||
import { createVite } from "../create-vite.js";
|
||||
import { createKey, getEnvironmentKey, hasEnvironmentKey } from "../encryption.js";
|
||||
import { levels, timerMessage } from "../logger/core.js";
|
||||
import { apply as applyPolyfill } from "../polyfill.js";
|
||||
import { createRouteManifest } from "../routing/index.js";
|
||||
import { getServerIslandRouteData } from "../server-islands/endpoint.js";
|
||||
import { clearContentLayerCache } from "../sync/index.js";
|
||||
import { ensureProcessNodeEnv, isServerLikeOutput } from "../util.js";
|
||||
import { collectPagesData } from "./page-data.js";
|
||||
import { staticBuild, viteBuild } from "./static-build.js";
|
||||
import { getTimeStat } from "./util.js";
|
||||
async function build(inlineConfig, options = {}) {
|
||||
ensureProcessNodeEnv("production");
|
||||
applyPolyfill();
|
||||
const logger = createNodeLogger(inlineConfig);
|
||||
const { userConfig, astroConfig } = await resolveConfig(inlineConfig, "build");
|
||||
telemetry.record(eventCliSession("build", userConfig));
|
||||
const settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root));
|
||||
if (inlineConfig.force) {
|
||||
if (astroConfig.experimental.contentCollectionCache) {
|
||||
const contentCacheDir = new URL("./content/", astroConfig.cacheDir);
|
||||
if (fs.existsSync(contentCacheDir)) {
|
||||
logger.debug("content", "clearing content cache");
|
||||
await fs.promises.rm(contentCacheDir, { force: true, recursive: true });
|
||||
logger.warn("content", "content cache cleared (force)");
|
||||
}
|
||||
}
|
||||
await clearContentLayerCache({ settings, logger, fs });
|
||||
}
|
||||
const builder = new AstroBuilder(settings, {
|
||||
...options,
|
||||
logger,
|
||||
mode: inlineConfig.mode
|
||||
});
|
||||
await builder.run();
|
||||
}
|
||||
class AstroBuilder {
|
||||
settings;
|
||||
logger;
|
||||
mode = "production";
|
||||
origin;
|
||||
manifest;
|
||||
timer;
|
||||
teardownCompiler;
|
||||
constructor(settings, options) {
|
||||
if (options.mode) {
|
||||
this.mode = options.mode;
|
||||
}
|
||||
this.settings = settings;
|
||||
this.logger = options.logger;
|
||||
this.teardownCompiler = options.teardownCompiler ?? true;
|
||||
this.origin = settings.config.site ? new URL(settings.config.site).origin : `http://localhost:${settings.config.server.port}`;
|
||||
this.manifest = { routes: [] };
|
||||
this.timer = {};
|
||||
}
|
||||
/** Setup Vite and run any async setup logic that couldn't run inside of the constructor. */
|
||||
async setup() {
|
||||
this.logger.debug("build", "Initial setup...");
|
||||
const { logger } = this;
|
||||
this.timer.init = performance.now();
|
||||
this.settings = await runHookConfigSetup({
|
||||
settings: this.settings,
|
||||
command: "build",
|
||||
logger
|
||||
});
|
||||
if (isServerLikeOutput(this.settings.config)) {
|
||||
this.settings = injectImageEndpoint(this.settings, "build");
|
||||
}
|
||||
this.manifest = createRouteManifest({ settings: this.settings }, this.logger);
|
||||
const viteConfig = await createVite(
|
||||
{
|
||||
mode: this.mode,
|
||||
server: {
|
||||
hmr: false,
|
||||
middlewareMode: true
|
||||
}
|
||||
},
|
||||
{
|
||||
settings: this.settings,
|
||||
logger: this.logger,
|
||||
mode: "build",
|
||||
command: "build",
|
||||
sync: false
|
||||
}
|
||||
);
|
||||
await runHookConfigDone({ settings: this.settings, logger });
|
||||
const { syncInternal } = await import("../sync/index.js");
|
||||
await syncInternal({
|
||||
settings: this.settings,
|
||||
logger,
|
||||
fs
|
||||
});
|
||||
return { viteConfig };
|
||||
}
|
||||
/** Run the build logic. build() is marked private because usage should go through ".run()" */
|
||||
async build({ viteConfig }) {
|
||||
await runHookBuildStart({ config: this.settings.config, logging: this.logger });
|
||||
this.validateConfig();
|
||||
this.logger.info("build", `output: ${blue('"' + this.settings.config.output + '"')}`);
|
||||
this.logger.info("build", `directory: ${blue(fileURLToPath(this.settings.config.outDir))}`);
|
||||
if (this.settings.adapter) {
|
||||
this.logger.info("build", `adapter: ${green(this.settings.adapter.name)}`);
|
||||
}
|
||||
this.logger.info("build", "Collecting build info...");
|
||||
this.timer.loadStart = performance.now();
|
||||
const { assets, allPages } = collectPagesData({
|
||||
settings: this.settings,
|
||||
logger: this.logger,
|
||||
manifest: this.manifest
|
||||
});
|
||||
this.logger.debug("build", timerMessage("All pages loaded", this.timer.loadStart));
|
||||
const pageNames = [];
|
||||
this.timer.buildStart = performance.now();
|
||||
this.logger.info(
|
||||
"build",
|
||||
green(`\u2713 Completed in ${getTimeStat(this.timer.init, performance.now())}.`)
|
||||
);
|
||||
const hasKey = hasEnvironmentKey();
|
||||
const keyPromise = hasKey ? getEnvironmentKey() : createKey();
|
||||
const opts = {
|
||||
allPages,
|
||||
settings: this.settings,
|
||||
logger: this.logger,
|
||||
manifest: this.manifest,
|
||||
mode: this.mode,
|
||||
origin: this.origin,
|
||||
pageNames,
|
||||
teardownCompiler: this.teardownCompiler,
|
||||
viteConfig,
|
||||
key: keyPromise
|
||||
};
|
||||
const { internals, ssrOutputChunkNames } = await viteBuild(opts);
|
||||
await staticBuild(opts, internals, ssrOutputChunkNames);
|
||||
this.timer.assetsStart = performance.now();
|
||||
Object.keys(assets).map((k) => {
|
||||
if (!assets[k]) return;
|
||||
const filePath = new URL(`file://${k}`);
|
||||
fs.mkdirSync(new URL("./", filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, assets[k], "utf8");
|
||||
delete assets[k];
|
||||
});
|
||||
this.logger.debug("build", timerMessage("Additional assets copied", this.timer.assetsStart));
|
||||
await runHookBuildDone({
|
||||
config: this.settings.config,
|
||||
pages: pageNames,
|
||||
routes: Object.values(allPages).flat().map((pageData) => pageData.route).concat(
|
||||
this.settings.config.experimental.serverIslands ? [getServerIslandRouteData(this.settings.config)] : []
|
||||
),
|
||||
logging: this.logger,
|
||||
cacheManifest: internals.cacheManifestUsed
|
||||
});
|
||||
if (this.logger.level && levels[this.logger.level()] <= levels["info"]) {
|
||||
await this.printStats({
|
||||
logger: this.logger,
|
||||
timeStart: this.timer.init,
|
||||
pageCount: pageNames.length,
|
||||
buildMode: this.settings.config.output
|
||||
});
|
||||
}
|
||||
}
|
||||
/** Build the given Astro project. */
|
||||
async run() {
|
||||
this.settings.timer.start("Total build");
|
||||
const setupData = await this.setup();
|
||||
try {
|
||||
await this.build(setupData);
|
||||
} catch (_err) {
|
||||
throw _err;
|
||||
} finally {
|
||||
this.settings.timer.end("Total build");
|
||||
this.settings.timer.writeStats();
|
||||
}
|
||||
}
|
||||
validateConfig() {
|
||||
const { config } = this.settings;
|
||||
if (config.outDir.toString() === config.root.toString()) {
|
||||
throw new Error(
|
||||
`the outDir cannot be the root folder. Please build to a folder such as dist.`
|
||||
);
|
||||
}
|
||||
}
|
||||
/** Stats */
|
||||
async printStats({
|
||||
logger,
|
||||
timeStart,
|
||||
pageCount,
|
||||
buildMode
|
||||
}) {
|
||||
const total = getTimeStat(timeStart, performance.now());
|
||||
let messages = [];
|
||||
if (buildMode === "static") {
|
||||
messages = [`${pageCount} page(s) built in`, bold(total)];
|
||||
} else {
|
||||
messages = ["Server built in", bold(total)];
|
||||
}
|
||||
logger.info("build", messages.join(" "));
|
||||
logger.info("build", `${bold("Complete!")}`);
|
||||
}
|
||||
}
|
||||
export {
|
||||
build as default
|
||||
};
|
139
node_modules/astro/dist/core/build/internal.d.ts
generated
vendored
Normal file
139
node_modules/astro/dist/core/build/internal.d.ts
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
import type { Rollup } from 'vite';
|
||||
import type { RouteData, SSRResult } from '../../@types/astro.js';
|
||||
import type { PageBuildData, StylesheetAsset, ViteID } from './types.js';
|
||||
export interface BuildInternals {
|
||||
/**
|
||||
* Each CSS module is named with a chunk id derived from the Astro pages they
|
||||
* are used in by default. It's easy to crawl this relation in the SSR build as
|
||||
* the Astro pages are the entrypoint, but not for the client build as hydratable
|
||||
* components are the entrypoint instead. This map is used as a cache from the SSR
|
||||
* build so the client can pick up the same information and use the same chunk ids.
|
||||
*/
|
||||
cssModuleToChunkIdMap: Map<string, string>;
|
||||
hoistedScriptIdToHoistedMap: Map<string, Set<string>>;
|
||||
hoistedScriptIdToPagesMap: Map<string, Set<string>>;
|
||||
/**
|
||||
* Used by the `directRenderScript` option. If script is inlined, its id and
|
||||
* inlined code is mapped here. The resolved id is an URL like "/_astro/something.js"
|
||||
* but will no longer exist as the content is now inlined in this map.
|
||||
*/
|
||||
inlinedScripts: Map<string, string>;
|
||||
entrySpecifierToBundleMap: Map<string, string>;
|
||||
/**
|
||||
* A map for page-specific information.
|
||||
*/
|
||||
pagesByKeys: Map<string, PageBuildData>;
|
||||
/**
|
||||
* A map for page-specific information by Vite ID (a path-like string)
|
||||
*/
|
||||
pagesByViteID: Map<ViteID, PageBuildData>;
|
||||
/**
|
||||
* A map for page-specific information by a client:only component
|
||||
*/
|
||||
pagesByClientOnly: Map<string, Set<PageBuildData>>;
|
||||
/**
|
||||
* A map for page-specific information by a script in an Astro file
|
||||
*/
|
||||
pagesByScriptId: Map<string, Set<PageBuildData>>;
|
||||
/**
|
||||
* A map of hydrated components to export names that are discovered during the SSR build.
|
||||
* These will be used as the top-level entrypoints for the client build.
|
||||
*
|
||||
* @example
|
||||
* '/project/Component1.jsx' => ['default']
|
||||
* '/project/Component2.jsx' => ['Counter', 'Timer']
|
||||
* '/project/Component3.jsx' => ['*']
|
||||
*/
|
||||
discoveredHydratedComponents: Map<string, string[]>;
|
||||
/**
|
||||
* A list of client:only components to export names that are discovered during the SSR build.
|
||||
* These will be used as the top-level entrypoints for the client build.
|
||||
*
|
||||
* @example
|
||||
* '/project/Component1.jsx' => ['default']
|
||||
* '/project/Component2.jsx' => ['Counter', 'Timer']
|
||||
* '/project/Component3.jsx' => ['*']
|
||||
*/
|
||||
discoveredClientOnlyComponents: Map<string, string[]>;
|
||||
/**
|
||||
* A list of hoisted scripts that are discovered during the SSR build
|
||||
* These will be used as the top-level entrypoints for the client build.
|
||||
*/
|
||||
discoveredScripts: Set<string>;
|
||||
cachedClientEntries: string[];
|
||||
cacheManifestUsed: boolean;
|
||||
/**
|
||||
* Map of propagated module ids (usually something like `/Users/...blog.mdx?astroPropagatedAssets`)
|
||||
* to a set of stylesheets that it uses.
|
||||
*/
|
||||
propagatedStylesMap: Map<string, Set<StylesheetAsset>>;
|
||||
/**
|
||||
* Map of propagated module ids (usually something like `/Users/...blog.mdx?astroPropagatedAssets`)
|
||||
* to a set of hoisted scripts that it uses.
|
||||
*/
|
||||
propagatedScriptsMap: Map<string, Set<string>>;
|
||||
staticFiles: Set<string>;
|
||||
ssrEntryChunk?: Rollup.OutputChunk;
|
||||
manifestEntryChunk?: Rollup.OutputChunk;
|
||||
manifestFileName?: string;
|
||||
entryPoints: Map<RouteData, URL>;
|
||||
componentMetadata: SSRResult['componentMetadata'];
|
||||
middlewareEntryPoint?: URL;
|
||||
/**
|
||||
* Chunks in the bundle that are only used in prerendering that we can delete later
|
||||
*/
|
||||
prerenderOnlyChunks: Rollup.OutputChunk[];
|
||||
}
|
||||
/**
|
||||
* Creates internal maps used to coordinate the CSS and HTML plugins.
|
||||
* @returns {BuildInternals}
|
||||
*/
|
||||
export declare function createBuildInternals(): BuildInternals;
|
||||
export declare function trackPageData(internals: BuildInternals, _component: string, pageData: PageBuildData, componentModuleId: string, componentURL: URL): void;
|
||||
/**
|
||||
* Tracks client-only components to the pages they are associated with.
|
||||
*/
|
||||
export declare function trackClientOnlyPageDatas(internals: BuildInternals, pageData: PageBuildData, clientOnlys: string[]): void;
|
||||
/**
|
||||
* Tracks scripts to the pages they are associated with. (experimental.directRenderScript)
|
||||
*/
|
||||
export declare function trackScriptPageDatas(internals: BuildInternals, pageData: PageBuildData, scriptIds: string[]): void;
|
||||
export declare function getPageDatasByClientOnlyID(internals: BuildInternals, viteid: ViteID): Generator<PageBuildData, void, unknown>;
|
||||
/**
|
||||
* From its route and component, get the page data from the build internals.
|
||||
* @param internals Build Internals with all the pages
|
||||
* @param route The route of the page, used to identify the page
|
||||
* @param component The component of the page, used to identify the page
|
||||
*/
|
||||
export declare function getPageData(internals: BuildInternals, route: string, component: string): PageBuildData | undefined;
|
||||
/**
|
||||
* Map internals.pagesByKeys to a new map with the public key instead of the internal key.
|
||||
* This function is only used to avoid breaking changes in the Integrations API, after we changed the way
|
||||
* we identify pages, from the entrypoint component to an internal key.
|
||||
* If the page component is unique -> the public key is the component path. (old behavior)
|
||||
* If the page component is shared -> the public key is the internal key. (new behavior)
|
||||
* The new behavior on shared entrypoint it's not a breaking change, because it was not supported before.
|
||||
* @param pagesByKeys A map of all page data by their internal key
|
||||
*/
|
||||
export declare function getPageDatasWithPublicKey(pagesByKeys: Map<string, PageBuildData>): Map<string, PageBuildData>;
|
||||
export declare function getPageDataByViteID(internals: BuildInternals, viteid: ViteID): PageBuildData | undefined;
|
||||
export declare function hasPrerenderedPages(internals: BuildInternals): boolean;
|
||||
interface OrderInfo {
|
||||
depth: number;
|
||||
order: number;
|
||||
}
|
||||
/**
|
||||
* Sort a page's CSS by depth. A higher depth means that the CSS comes from shared subcomponents.
|
||||
* A lower depth means it comes directly from the top-level page.
|
||||
* Can be used to sort stylesheets so that shared rules come first
|
||||
* and page-specific rules come after.
|
||||
*/
|
||||
export declare function cssOrder(a: OrderInfo, b: OrderInfo): 1 | -1;
|
||||
export declare function mergeInlineCss(acc: Array<StylesheetAsset>, current: StylesheetAsset): Array<StylesheetAsset>;
|
||||
/**
|
||||
* Get all pages data from the build internals, using a specific hoisted script id.
|
||||
* @param internals Build Internals with all the pages
|
||||
* @param id Hoisted script id, used to identify the pages using it
|
||||
*/
|
||||
export declare function getPageDatasByHoistedScriptId(internals: BuildInternals, id: string): PageBuildData[];
|
||||
export {};
|
182
node_modules/astro/dist/core/build/internal.js
generated
vendored
Normal file
182
node_modules/astro/dist/core/build/internal.js
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
import { prependForwardSlash, removeFileExtension } from "../path.js";
|
||||
import { viteID } from "../util.js";
|
||||
import { makePageDataKey } from "./plugins/util.js";
|
||||
function createBuildInternals() {
|
||||
const hoistedScriptIdToHoistedMap = /* @__PURE__ */ new Map();
|
||||
const hoistedScriptIdToPagesMap = /* @__PURE__ */ new Map();
|
||||
return {
|
||||
cachedClientEntries: [],
|
||||
cssModuleToChunkIdMap: /* @__PURE__ */ new Map(),
|
||||
hoistedScriptIdToHoistedMap,
|
||||
hoistedScriptIdToPagesMap,
|
||||
inlinedScripts: /* @__PURE__ */ new Map(),
|
||||
entrySpecifierToBundleMap: /* @__PURE__ */ new Map(),
|
||||
pagesByKeys: /* @__PURE__ */ new Map(),
|
||||
pagesByViteID: /* @__PURE__ */ new Map(),
|
||||
pagesByClientOnly: /* @__PURE__ */ new Map(),
|
||||
pagesByScriptId: /* @__PURE__ */ new Map(),
|
||||
propagatedStylesMap: /* @__PURE__ */ new Map(),
|
||||
propagatedScriptsMap: /* @__PURE__ */ new Map(),
|
||||
discoveredHydratedComponents: /* @__PURE__ */ new Map(),
|
||||
discoveredClientOnlyComponents: /* @__PURE__ */ new Map(),
|
||||
discoveredScripts: /* @__PURE__ */ new Set(),
|
||||
staticFiles: /* @__PURE__ */ new Set(),
|
||||
componentMetadata: /* @__PURE__ */ new Map(),
|
||||
entryPoints: /* @__PURE__ */ new Map(),
|
||||
cacheManifestUsed: false,
|
||||
prerenderOnlyChunks: []
|
||||
};
|
||||
}
|
||||
function trackPageData(internals, _component, pageData, componentModuleId, componentURL) {
|
||||
pageData.moduleSpecifier = componentModuleId;
|
||||
internals.pagesByKeys.set(pageData.key, pageData);
|
||||
internals.pagesByViteID.set(viteID(componentURL), pageData);
|
||||
}
|
||||
function trackClientOnlyPageDatas(internals, pageData, clientOnlys) {
|
||||
for (const clientOnlyComponent of clientOnlys) {
|
||||
let pageDataSet;
|
||||
if (internals.pagesByClientOnly.has(clientOnlyComponent)) {
|
||||
pageDataSet = internals.pagesByClientOnly.get(clientOnlyComponent);
|
||||
} else {
|
||||
pageDataSet = /* @__PURE__ */ new Set();
|
||||
internals.pagesByClientOnly.set(clientOnlyComponent, pageDataSet);
|
||||
}
|
||||
pageDataSet.add(pageData);
|
||||
}
|
||||
}
|
||||
function trackScriptPageDatas(internals, pageData, scriptIds) {
|
||||
for (const scriptId of scriptIds) {
|
||||
let pageDataSet;
|
||||
if (internals.pagesByScriptId.has(scriptId)) {
|
||||
pageDataSet = internals.pagesByScriptId.get(scriptId);
|
||||
} else {
|
||||
pageDataSet = /* @__PURE__ */ new Set();
|
||||
internals.pagesByScriptId.set(scriptId, pageDataSet);
|
||||
}
|
||||
pageDataSet.add(pageData);
|
||||
}
|
||||
}
|
||||
function* getPageDatasByClientOnlyID(internals, viteid) {
|
||||
const pagesByClientOnly = internals.pagesByClientOnly;
|
||||
if (pagesByClientOnly.size) {
|
||||
let pageBuildDatas = pagesByClientOnly.get(viteid);
|
||||
if (!pageBuildDatas) {
|
||||
let pathname = `/@fs${prependForwardSlash(viteid)}`;
|
||||
pageBuildDatas = pagesByClientOnly.get(pathname);
|
||||
}
|
||||
if (!pageBuildDatas) {
|
||||
let pathname = `/@fs${prependForwardSlash(removeFileExtension(viteid))}`;
|
||||
pageBuildDatas = pagesByClientOnly.get(pathname);
|
||||
}
|
||||
if (pageBuildDatas) {
|
||||
for (const pageData of pageBuildDatas) {
|
||||
yield pageData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function getPageData(internals, route, component) {
|
||||
let pageData = internals.pagesByKeys.get(makePageDataKey(route, component));
|
||||
if (pageData) {
|
||||
return pageData;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function getPagesDatasByComponent(internals, component) {
|
||||
const pageDatas = [];
|
||||
internals.pagesByKeys.forEach((pageData) => {
|
||||
if (component === pageData.component) pageDatas.push(pageData);
|
||||
});
|
||||
return pageDatas;
|
||||
}
|
||||
function getPageDatasWithPublicKey(pagesByKeys) {
|
||||
const pagesWithPublicKey = /* @__PURE__ */ new Map();
|
||||
const pagesByComponentsArray = Array.from(pagesByKeys.values()).map((pageData) => {
|
||||
return { component: pageData.component, pageData };
|
||||
});
|
||||
const pagesWithUniqueComponent = pagesByComponentsArray.filter((page) => {
|
||||
return pagesByComponentsArray.filter((p) => p.component === page.component).length === 1;
|
||||
});
|
||||
pagesWithUniqueComponent.forEach((page) => {
|
||||
pagesWithPublicKey.set(page.component, page.pageData);
|
||||
});
|
||||
const pagesWithSharedComponent = pagesByComponentsArray.filter((page) => {
|
||||
return pagesByComponentsArray.filter((p) => p.component === page.component).length > 1;
|
||||
});
|
||||
pagesWithSharedComponent.forEach((page) => {
|
||||
pagesWithPublicKey.set(page.pageData.key, page.pageData);
|
||||
});
|
||||
return pagesWithPublicKey;
|
||||
}
|
||||
function getPageDataByViteID(internals, viteid) {
|
||||
if (internals.pagesByViteID.has(viteid)) {
|
||||
return internals.pagesByViteID.get(viteid);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function hasPrerenderedPages(internals) {
|
||||
for (const pageData of internals.pagesByKeys.values()) {
|
||||
if (pageData.route.prerender) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function cssOrder(a, b) {
|
||||
let depthA = a.depth, depthB = b.depth, orderA = a.order, orderB = b.order;
|
||||
if (orderA === -1 && orderB >= 0) {
|
||||
return 1;
|
||||
} else if (orderB === -1 && orderA >= 0) {
|
||||
return -1;
|
||||
} else if (orderA > orderB) {
|
||||
return 1;
|
||||
} else if (orderA < orderB) {
|
||||
return -1;
|
||||
} else {
|
||||
if (depthA === -1) {
|
||||
return -1;
|
||||
} else if (depthB === -1) {
|
||||
return 1;
|
||||
} else {
|
||||
return depthA > depthB ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
function mergeInlineCss(acc, current) {
|
||||
const lastAdded = acc.at(acc.length - 1);
|
||||
const lastWasInline = lastAdded?.type === "inline";
|
||||
const currentIsInline = current?.type === "inline";
|
||||
if (lastWasInline && currentIsInline) {
|
||||
const merged = { type: "inline", content: lastAdded.content + current.content };
|
||||
acc[acc.length - 1] = merged;
|
||||
return acc;
|
||||
}
|
||||
acc.push(current);
|
||||
return acc;
|
||||
}
|
||||
function getPageDatasByHoistedScriptId(internals, id) {
|
||||
const set = internals.hoistedScriptIdToPagesMap.get(id);
|
||||
const pageDatas = [];
|
||||
if (set) {
|
||||
for (const pageId of set) {
|
||||
getPagesDatasByComponent(internals, pageId.slice(1)).forEach((pageData) => {
|
||||
pageDatas.push(pageData);
|
||||
});
|
||||
}
|
||||
}
|
||||
return pageDatas;
|
||||
}
|
||||
export {
|
||||
createBuildInternals,
|
||||
cssOrder,
|
||||
getPageData,
|
||||
getPageDataByViteID,
|
||||
getPageDatasByClientOnlyID,
|
||||
getPageDatasByHoistedScriptId,
|
||||
getPageDatasWithPublicKey,
|
||||
hasPrerenderedPages,
|
||||
mergeInlineCss,
|
||||
trackClientOnlyPageDatas,
|
||||
trackPageData,
|
||||
trackScriptPageDatas
|
||||
};
|
13
node_modules/astro/dist/core/build/page-data.d.ts
generated
vendored
Normal file
13
node_modules/astro/dist/core/build/page-data.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { AstroSettings, ManifestData } from '../../@types/astro.js';
|
||||
import type { Logger } from '../logger/core.js';
|
||||
import type { AllPagesData } from './types.js';
|
||||
export interface CollectPagesDataOptions {
|
||||
settings: AstroSettings;
|
||||
logger: Logger;
|
||||
manifest: ManifestData;
|
||||
}
|
||||
export interface CollectPagesDataResult {
|
||||
assets: Record<string, string>;
|
||||
allPages: AllPagesData;
|
||||
}
|
||||
export declare function collectPagesData(opts: CollectPagesDataOptions): CollectPagesDataResult;
|
43
node_modules/astro/dist/core/build/page-data.js
generated
vendored
Normal file
43
node_modules/astro/dist/core/build/page-data.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import * as colors from "kleur/colors";
|
||||
import { debug } from "../logger/core.js";
|
||||
import { makePageDataKey } from "./plugins/util.js";
|
||||
function collectPagesData(opts) {
|
||||
const { settings, manifest } = opts;
|
||||
const assets = {};
|
||||
const allPages = {};
|
||||
for (const route of manifest.routes) {
|
||||
const key = makePageDataKey(route.route, route.component);
|
||||
if (route.pathname) {
|
||||
allPages[key] = {
|
||||
key,
|
||||
component: route.component,
|
||||
route,
|
||||
moduleSpecifier: "",
|
||||
styles: [],
|
||||
hoistedScript: void 0
|
||||
};
|
||||
if (settings.config.output === "static") {
|
||||
const html = `${route.pathname}`.replace(/\/?$/, "/index.html");
|
||||
debug(
|
||||
"build",
|
||||
`\u251C\u2500\u2500 ${colors.bold(colors.green("\u2714"))} ${route.component} \u2192 ${colors.yellow(html)}`
|
||||
);
|
||||
} else {
|
||||
debug("build", `\u251C\u2500\u2500 ${colors.bold(colors.green("\u2714"))} ${route.component}`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
allPages[key] = {
|
||||
key,
|
||||
component: route.component,
|
||||
route,
|
||||
moduleSpecifier: "",
|
||||
styles: [],
|
||||
hoistedScript: void 0
|
||||
};
|
||||
}
|
||||
return { assets, allPages };
|
||||
}
|
||||
export {
|
||||
collectPagesData
|
||||
};
|
51
node_modules/astro/dist/core/build/pipeline.d.ts
generated
vendored
Normal file
51
node_modules/astro/dist/core/build/pipeline.d.ts
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { ComponentInstance, RewritePayload, RouteData, SSRResult } from '../../@types/astro.js';
|
||||
import type { SSRManifest } from '../app/types.js';
|
||||
import type { TryRewriteResult } from '../base-pipeline.js';
|
||||
import { Pipeline } from '../render/index.js';
|
||||
import { type BuildInternals } from './internal.js';
|
||||
import type { PageBuildData, SinglePageBuiltModule, StaticBuildOptions } from './types.js';
|
||||
/**
|
||||
* The build pipeline is responsible to gather the files emitted by the SSR build and generate the pages by executing these files.
|
||||
*/
|
||||
export declare class BuildPipeline extends Pipeline {
|
||||
#private;
|
||||
readonly internals: BuildInternals;
|
||||
readonly manifest: SSRManifest;
|
||||
readonly options: StaticBuildOptions;
|
||||
readonly config: import("../../@types/astro.js").AstroConfig;
|
||||
readonly settings: import("../../@types/astro.js").AstroSettings;
|
||||
readonly defaultRoutes: {
|
||||
instance: ComponentInstance;
|
||||
matchesComponent(filePath: URL): boolean;
|
||||
route: string;
|
||||
component: string;
|
||||
}[];
|
||||
get outFolder(): URL;
|
||||
private constructor();
|
||||
getRoutes(): RouteData[];
|
||||
static create({ internals, manifest, options, }: Pick<BuildPipeline, 'internals' | 'manifest' | 'options'>): BuildPipeline;
|
||||
/**
|
||||
* The SSR build emits two important files:
|
||||
* - dist/server/manifest.mjs
|
||||
* - dist/renderers.mjs
|
||||
*
|
||||
* These two files, put together, will be used to generate the pages.
|
||||
*
|
||||
* ## Errors
|
||||
*
|
||||
* It will throw errors if the previous files can't be found in the file system.
|
||||
*
|
||||
* @param staticBuildOptions
|
||||
*/
|
||||
static retrieveManifest(staticBuildOptions: StaticBuildOptions, internals: BuildInternals): Promise<SSRManifest>;
|
||||
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'>;
|
||||
componentMetadata(): void;
|
||||
/**
|
||||
* It collects the routes to generate during the build.
|
||||
* It returns a map of page information and their relative entry point as a string.
|
||||
*/
|
||||
retrieveRoutesToGenerate(): Map<PageBuildData, string>;
|
||||
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
||||
tryRewrite(payload: RewritePayload, request: Request): Promise<TryRewriteResult>;
|
||||
retrieveSsrEntry(route: RouteData, filePath: string): Promise<SinglePageBuiltModule>;
|
||||
}
|
287
node_modules/astro/dist/core/build/pipeline.js
generated
vendored
Normal file
287
node_modules/astro/dist/core/build/pipeline.js
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
import { getOutputDirectory } from "../../prerender/utils.js";
|
||||
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
||||
import { routeIsFallback, routeIsRedirect } from "../redirects/helpers.js";
|
||||
import { RedirectSinglePageBuiltModule } from "../redirects/index.js";
|
||||
import { Pipeline } from "../render/index.js";
|
||||
import {
|
||||
createAssetLink,
|
||||
createModuleScriptsSet,
|
||||
createStylesheetElementSet
|
||||
} from "../render/ssr-element.js";
|
||||
import { createDefaultRoutes } from "../routing/default.js";
|
||||
import { findRouteToRewrite } from "../routing/rewrite.js";
|
||||
import { isServerLikeOutput } from "../util.js";
|
||||
import { getOutDirWithinCwd } from "./common.js";
|
||||
import { cssOrder, getPageData, mergeInlineCss } from "./internal.js";
|
||||
import { ASTRO_PAGE_MODULE_ID, ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
|
||||
import { RESOLVED_SPLIT_MODULE_ID } from "./plugins/plugin-ssr.js";
|
||||
import { getPagesFromVirtualModulePageName, getVirtualModulePageName } from "./plugins/util.js";
|
||||
import { i18nHasFallback } from "./util.js";
|
||||
class BuildPipeline extends Pipeline {
|
||||
constructor(internals, manifest, options, config = options.settings.config, settings = options.settings, defaultRoutes = createDefaultRoutes(manifest)) {
|
||||
const resolveCache = /* @__PURE__ */ new Map();
|
||||
async function resolve(specifier) {
|
||||
if (resolveCache.has(specifier)) {
|
||||
return resolveCache.get(specifier);
|
||||
}
|
||||
const hashedFilePath = manifest.entryModules[specifier];
|
||||
if (typeof hashedFilePath !== "string" || hashedFilePath === "") {
|
||||
if (specifier === BEFORE_HYDRATION_SCRIPT_ID) {
|
||||
resolveCache.set(specifier, "");
|
||||
return "";
|
||||
}
|
||||
throw new Error(`Cannot find the built path for ${specifier}`);
|
||||
}
|
||||
const assetLink = createAssetLink(hashedFilePath, manifest.base, manifest.assetsPrefix);
|
||||
resolveCache.set(specifier, assetLink);
|
||||
return assetLink;
|
||||
}
|
||||
const serverLike = isServerLikeOutput(config);
|
||||
const streaming = serverLike;
|
||||
super(
|
||||
options.logger,
|
||||
manifest,
|
||||
options.mode,
|
||||
manifest.renderers,
|
||||
resolve,
|
||||
serverLike,
|
||||
streaming
|
||||
);
|
||||
this.internals = internals;
|
||||
this.manifest = manifest;
|
||||
this.options = options;
|
||||
this.config = config;
|
||||
this.settings = settings;
|
||||
this.defaultRoutes = defaultRoutes;
|
||||
}
|
||||
#componentsInterner = /* @__PURE__ */ new WeakMap();
|
||||
/**
|
||||
* This cache is needed to map a single `RouteData` to its file path.
|
||||
* @private
|
||||
*/
|
||||
#routesByFilePath = /* @__PURE__ */ new WeakMap();
|
||||
get outFolder() {
|
||||
const ssr = isServerLikeOutput(this.settings.config);
|
||||
return ssr ? this.settings.config.build.server : getOutDirWithinCwd(this.settings.config.outDir);
|
||||
}
|
||||
getRoutes() {
|
||||
return this.options.manifest.routes;
|
||||
}
|
||||
static create({
|
||||
internals,
|
||||
manifest,
|
||||
options
|
||||
}) {
|
||||
return new BuildPipeline(internals, manifest, options);
|
||||
}
|
||||
/**
|
||||
* The SSR build emits two important files:
|
||||
* - dist/server/manifest.mjs
|
||||
* - dist/renderers.mjs
|
||||
*
|
||||
* These two files, put together, will be used to generate the pages.
|
||||
*
|
||||
* ## Errors
|
||||
*
|
||||
* It will throw errors if the previous files can't be found in the file system.
|
||||
*
|
||||
* @param staticBuildOptions
|
||||
*/
|
||||
static async retrieveManifest(staticBuildOptions, internals) {
|
||||
const config = staticBuildOptions.settings.config;
|
||||
const baseDirectory = getOutputDirectory(config);
|
||||
const manifestEntryUrl = new URL(
|
||||
`${internals.manifestFileName}?time=${Date.now()}`,
|
||||
baseDirectory
|
||||
);
|
||||
const { manifest } = await import(manifestEntryUrl.toString());
|
||||
if (!manifest) {
|
||||
throw new Error(
|
||||
"Astro couldn't find the emitted manifest. This is an internal error, please file an issue."
|
||||
);
|
||||
}
|
||||
const renderersEntryUrl = new URL(`renderers.mjs?time=${Date.now()}`, baseDirectory);
|
||||
const renderers = await import(renderersEntryUrl.toString());
|
||||
const middleware = internals.middlewareEntryPoint ? await import(internals.middlewareEntryPoint.toString()).then((mod) => {
|
||||
return function() {
|
||||
return { onRequest: mod.onRequest };
|
||||
};
|
||||
}) : manifest.middleware;
|
||||
if (!renderers) {
|
||||
throw new Error(
|
||||
"Astro couldn't find the emitted renderers. This is an internal error, please file an issue."
|
||||
);
|
||||
}
|
||||
return {
|
||||
...manifest,
|
||||
renderers: renderers.renderers,
|
||||
middleware
|
||||
};
|
||||
}
|
||||
headElements(routeData) {
|
||||
const {
|
||||
internals,
|
||||
manifest: { assetsPrefix, base },
|
||||
settings
|
||||
} = this;
|
||||
const links = /* @__PURE__ */ new Set();
|
||||
const pageBuildData = getPageData(internals, routeData.route, routeData.component);
|
||||
const scripts = createModuleScriptsSet(
|
||||
pageBuildData?.hoistedScript ? [pageBuildData.hoistedScript] : [],
|
||||
base,
|
||||
assetsPrefix
|
||||
);
|
||||
const sortedCssAssets = pageBuildData?.styles.sort(cssOrder).map(({ sheet }) => sheet).reduce(mergeInlineCss, []);
|
||||
const styles = createStylesheetElementSet(sortedCssAssets ?? [], base, assetsPrefix);
|
||||
if (settings.scripts.some((script) => script.stage === "page")) {
|
||||
const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID);
|
||||
if (typeof hashedFilePath !== "string") {
|
||||
throw new Error(`Cannot find the built path for ${PAGE_SCRIPT_ID}`);
|
||||
}
|
||||
const src = createAssetLink(hashedFilePath, base, assetsPrefix);
|
||||
scripts.add({
|
||||
props: { type: "module", src },
|
||||
children: ""
|
||||
});
|
||||
}
|
||||
for (const script of settings.scripts) {
|
||||
if (script.stage === "head-inline") {
|
||||
scripts.add({
|
||||
props: {},
|
||||
children: script.content
|
||||
});
|
||||
}
|
||||
}
|
||||
return { scripts, styles, links };
|
||||
}
|
||||
componentMetadata() {
|
||||
}
|
||||
/**
|
||||
* It collects the routes to generate during the build.
|
||||
* It returns a map of page information and their relative entry point as a string.
|
||||
*/
|
||||
retrieveRoutesToGenerate() {
|
||||
const pages = /* @__PURE__ */ new Map();
|
||||
for (const [virtualModulePageName, filePath] of this.internals.entrySpecifierToBundleMap) {
|
||||
if (virtualModulePageName.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || virtualModulePageName.includes(RESOLVED_SPLIT_MODULE_ID)) {
|
||||
let pageDatas = [];
|
||||
if (virtualModulePageName.includes(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
|
||||
pageDatas.push(
|
||||
...getPagesFromVirtualModulePageName(
|
||||
this.internals,
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
virtualModulePageName
|
||||
)
|
||||
);
|
||||
}
|
||||
if (virtualModulePageName.includes(RESOLVED_SPLIT_MODULE_ID)) {
|
||||
pageDatas.push(
|
||||
...getPagesFromVirtualModulePageName(
|
||||
this.internals,
|
||||
RESOLVED_SPLIT_MODULE_ID,
|
||||
virtualModulePageName
|
||||
)
|
||||
);
|
||||
}
|
||||
for (const pageData of pageDatas) {
|
||||
pages.set(pageData, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const pageData of this.internals.pagesByKeys.values()) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
pages.set(pageData, pageData.component);
|
||||
} else if (routeIsFallback(pageData.route) && (i18nHasFallback(this.config) || routeIsFallback(pageData.route) && pageData.route.route === "/")) {
|
||||
const moduleSpecifier = getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component);
|
||||
const filePath = this.internals.entrySpecifierToBundleMap.get(moduleSpecifier);
|
||||
if (filePath) {
|
||||
pages.set(pageData, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const [buildData, filePath] of pages.entries()) {
|
||||
this.#routesByFilePath.set(buildData.route, filePath);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
async getComponentByRoute(routeData) {
|
||||
if (this.#componentsInterner.has(routeData)) {
|
||||
const entry = this.#componentsInterner.get(routeData);
|
||||
return await entry.page();
|
||||
}
|
||||
for (const route of this.defaultRoutes) {
|
||||
if (route.component === routeData.component) {
|
||||
return route.instance;
|
||||
}
|
||||
}
|
||||
const filePath = this.#routesByFilePath.get(routeData);
|
||||
const module = await this.retrieveSsrEntry(routeData, filePath);
|
||||
return module.page();
|
||||
}
|
||||
async tryRewrite(payload, request) {
|
||||
const { routeData, pathname, newUrl } = findRouteToRewrite({
|
||||
payload,
|
||||
request,
|
||||
routes: this.options.manifest.routes,
|
||||
trailingSlash: this.config.trailingSlash,
|
||||
buildFormat: this.config.build.format,
|
||||
base: this.config.base
|
||||
});
|
||||
const componentInstance = await this.getComponentByRoute(routeData);
|
||||
return { routeData, componentInstance, newUrl, pathname };
|
||||
}
|
||||
async retrieveSsrEntry(route, filePath) {
|
||||
if (this.#componentsInterner.has(route)) {
|
||||
return this.#componentsInterner.get(route);
|
||||
}
|
||||
let entry;
|
||||
if (routeIsRedirect(route)) {
|
||||
entry = await this.#getEntryForRedirectRoute(route, this.internals, this.outFolder);
|
||||
} else if (routeIsFallback(route)) {
|
||||
entry = await this.#getEntryForFallbackRoute(route, this.internals, this.outFolder);
|
||||
} else {
|
||||
const ssrEntryURLPage = createEntryURL(filePath, this.outFolder);
|
||||
entry = await import(ssrEntryURLPage.toString());
|
||||
}
|
||||
this.#componentsInterner.set(route, entry);
|
||||
return entry;
|
||||
}
|
||||
async #getEntryForFallbackRoute(route, _internals, outFolder) {
|
||||
if (route.type !== "fallback") {
|
||||
throw new Error(`Expected a redirect route.`);
|
||||
}
|
||||
if (route.redirectRoute) {
|
||||
const filePath = getEntryFilePath(this.internals, route.redirectRoute);
|
||||
if (filePath) {
|
||||
const url = createEntryURL(filePath, outFolder);
|
||||
const ssrEntryPage = await import(url.toString());
|
||||
return ssrEntryPage;
|
||||
}
|
||||
}
|
||||
return RedirectSinglePageBuiltModule;
|
||||
}
|
||||
async #getEntryForRedirectRoute(route, _internals, outFolder) {
|
||||
if (route.type !== "redirect") {
|
||||
throw new Error(`Expected a redirect route.`);
|
||||
}
|
||||
if (route.redirectRoute) {
|
||||
const filePath = getEntryFilePath(this.internals, route.redirectRoute);
|
||||
if (filePath) {
|
||||
const url = createEntryURL(filePath, outFolder);
|
||||
const ssrEntryPage = await import(url.toString());
|
||||
return ssrEntryPage;
|
||||
}
|
||||
}
|
||||
return RedirectSinglePageBuiltModule;
|
||||
}
|
||||
}
|
||||
function createEntryURL(filePath, outFolder) {
|
||||
return new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
|
||||
}
|
||||
function getEntryFilePath(internals, pageData) {
|
||||
const id = "\0" + getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component);
|
||||
return internals.entrySpecifierToBundleMap.get(id);
|
||||
}
|
||||
export {
|
||||
BuildPipeline
|
||||
};
|
43
node_modules/astro/dist/core/build/plugin.d.ts
generated
vendored
Normal file
43
node_modules/astro/dist/core/build/plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { Rollup, Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from './internal.js';
|
||||
import type { StaticBuildOptions, ViteBuildReturn } from './types.js';
|
||||
type RollupOutputArray = Extract<ViteBuildReturn, Array<any>>;
|
||||
type OutputChunkorAsset = RollupOutputArray[number]['output'][number];
|
||||
type OutputChunk = Extract<OutputChunkorAsset, {
|
||||
type: 'chunk';
|
||||
}>;
|
||||
export type BuildTarget = 'server' | 'client';
|
||||
type MutateChunk = (chunk: OutputChunk, targets: BuildTarget[], newCode: string) => void;
|
||||
export interface BuildBeforeHookResult {
|
||||
enforce?: 'after-user-plugins';
|
||||
vitePlugin: VitePlugin | VitePlugin[] | undefined;
|
||||
}
|
||||
export type AstroBuildPlugin = {
|
||||
targets: BuildTarget[];
|
||||
hooks?: {
|
||||
'build:before'?: (opts: {
|
||||
target: BuildTarget;
|
||||
input: Set<string>;
|
||||
}) => BuildBeforeHookResult | Promise<BuildBeforeHookResult>;
|
||||
'build:post'?: (opts: {
|
||||
ssrOutputs: RollupOutputArray;
|
||||
clientOutputs: RollupOutputArray;
|
||||
mutate: MutateChunk;
|
||||
}) => void | Promise<void>;
|
||||
};
|
||||
};
|
||||
export declare function createPluginContainer(options: StaticBuildOptions, internals: BuildInternals): {
|
||||
options: StaticBuildOptions;
|
||||
internals: BuildInternals;
|
||||
register(plugin: AstroBuildPlugin): void;
|
||||
runBeforeHook(target: BuildTarget, input: Set<string>): Promise<{
|
||||
vitePlugins: (VitePlugin<any> | VitePlugin<any>[])[];
|
||||
lastVitePlugins: (VitePlugin<any> | VitePlugin<any>[])[];
|
||||
}>;
|
||||
runPostHook(ssrOutputs: Rollup.RollupOutput[], clientOutputs: Rollup.RollupOutput[]): Promise<Map<string, {
|
||||
targets: BuildTarget[];
|
||||
code: string;
|
||||
}>>;
|
||||
};
|
||||
export type AstroBuildPluginContainer = ReturnType<typeof createPluginContainer>;
|
||||
export {};
|
61
node_modules/astro/dist/core/build/plugin.js
generated
vendored
Normal file
61
node_modules/astro/dist/core/build/plugin.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
function createPluginContainer(options, internals) {
|
||||
const plugins = /* @__PURE__ */ new Map();
|
||||
const allPlugins = /* @__PURE__ */ new Set();
|
||||
for (const target of ["client", "server"]) {
|
||||
plugins.set(target, []);
|
||||
}
|
||||
return {
|
||||
options,
|
||||
internals,
|
||||
register(plugin) {
|
||||
allPlugins.add(plugin);
|
||||
for (const target of plugin.targets) {
|
||||
const targetPlugins = plugins.get(target) ?? [];
|
||||
targetPlugins.push(plugin);
|
||||
plugins.set(target, targetPlugins);
|
||||
}
|
||||
},
|
||||
// Hooks
|
||||
async runBeforeHook(target, input) {
|
||||
let targetPlugins = plugins.get(target) ?? [];
|
||||
let vitePlugins = [];
|
||||
let lastVitePlugins = [];
|
||||
for (const plugin of targetPlugins) {
|
||||
if (plugin.hooks?.["build:before"]) {
|
||||
let result = await plugin.hooks["build:before"]({ target, input });
|
||||
if (result.vitePlugin) {
|
||||
vitePlugins.push(result.vitePlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
vitePlugins,
|
||||
lastVitePlugins
|
||||
};
|
||||
},
|
||||
async runPostHook(ssrOutputs, clientOutputs) {
|
||||
const mutations = /* @__PURE__ */ new Map();
|
||||
const mutate = (chunk, targets, newCode) => {
|
||||
chunk.code = newCode;
|
||||
mutations.set(chunk.fileName, {
|
||||
targets,
|
||||
code: newCode
|
||||
});
|
||||
};
|
||||
for (const plugin of allPlugins) {
|
||||
const postHook = plugin.hooks?.["build:post"];
|
||||
if (postHook) {
|
||||
await postHook({
|
||||
ssrOutputs,
|
||||
clientOutputs,
|
||||
mutate
|
||||
});
|
||||
}
|
||||
}
|
||||
return mutations;
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
createPluginContainer
|
||||
};
|
2
node_modules/astro/dist/core/build/plugins/index.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/build/plugins/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { AstroBuildPluginContainer } from '../plugin.js';
|
||||
export declare function registerAllPlugins({ internals, options, register }: AstroBuildPluginContainer): void;
|
41
node_modules/astro/dist/core/build/plugins/index.js
generated
vendored
Normal file
41
node_modules/astro/dist/core/build/plugins/index.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { astroConfigBuildPlugin } from "../../../content/vite-plugin-content-assets.js";
|
||||
import { astroHeadBuildPlugin } from "../../../vite-plugin-head/index.js";
|
||||
import { pluginAnalyzer } from "./plugin-analyzer.js";
|
||||
import { pluginChunks } from "./plugin-chunks.js";
|
||||
import { pluginComponentEntry } from "./plugin-component-entry.js";
|
||||
import { pluginContent } from "./plugin-content.js";
|
||||
import { pluginCSS } from "./plugin-css.js";
|
||||
import { pluginHoistedScripts } from "./plugin-hoisted-scripts.js";
|
||||
import { pluginInternals } from "./plugin-internals.js";
|
||||
import { pluginManifest } from "./plugin-manifest.js";
|
||||
import { pluginMiddleware } from "./plugin-middleware.js";
|
||||
import { pluginPages } from "./plugin-pages.js";
|
||||
import { pluginPrerender } from "./plugin-prerender.js";
|
||||
import { pluginRenderers } from "./plugin-renderers.js";
|
||||
import { pluginScripts } from "./plugin-scripts.js";
|
||||
import { pluginSSR, pluginSSRSplit } from "./plugin-ssr.js";
|
||||
function registerAllPlugins({ internals, options, register }) {
|
||||
register(pluginComponentEntry(internals));
|
||||
register(pluginAnalyzer(options, internals));
|
||||
register(pluginInternals(internals));
|
||||
register(pluginManifest(options, internals));
|
||||
register(pluginRenderers(options));
|
||||
register(pluginMiddleware(options, internals));
|
||||
register(pluginPages(options, internals));
|
||||
register(pluginContent(options, internals));
|
||||
register(pluginCSS(options, internals));
|
||||
register(astroHeadBuildPlugin(internals));
|
||||
register(pluginPrerender(options, internals));
|
||||
register(astroConfigBuildPlugin(options, internals));
|
||||
if (options.settings.config.experimental.directRenderScript) {
|
||||
register(pluginScripts(internals));
|
||||
} else {
|
||||
register(pluginHoistedScripts(internals));
|
||||
}
|
||||
register(pluginSSR(options, internals));
|
||||
register(pluginSSRSplit(options, internals));
|
||||
register(pluginChunks());
|
||||
}
|
||||
export {
|
||||
registerAllPlugins
|
||||
};
|
6
node_modules/astro/dist/core/build/plugins/plugin-analyzer.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/core/build/plugins/plugin-analyzer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare function vitePluginAnalyzer(options: StaticBuildOptions, internals: BuildInternals): VitePlugin;
|
||||
export declare function pluginAnalyzer(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
162
node_modules/astro/dist/core/build/plugins/plugin-analyzer.js
generated
vendored
Normal file
162
node_modules/astro/dist/core/build/plugins/plugin-analyzer.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
import { PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
|
||||
import { prependForwardSlash } from "../../../core/path.js";
|
||||
import {
|
||||
getParentModuleInfos,
|
||||
getTopLevelPageModuleInfos,
|
||||
moduleIsTopLevelPage
|
||||
} from "../graph.js";
|
||||
import {
|
||||
getPageDataByViteID,
|
||||
trackClientOnlyPageDatas,
|
||||
trackScriptPageDatas
|
||||
} from "../internal.js";
|
||||
function isPropagatedAsset(id) {
|
||||
try {
|
||||
return new URL("file://" + id).searchParams.has(PROPAGATED_ASSET_FLAG);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function vitePluginAnalyzer(options, internals) {
|
||||
function hoistedScriptScanner() {
|
||||
const uniqueHoistedIds = /* @__PURE__ */ new Map();
|
||||
const pageScriptsMap = /* @__PURE__ */ new Map();
|
||||
return {
|
||||
async scan(scripts, from) {
|
||||
const hoistedScripts = /* @__PURE__ */ new Set();
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
const hid = `${from.replace("/@fs", "")}?astro&type=script&index=${i}&lang.ts`;
|
||||
hoistedScripts.add(hid);
|
||||
}
|
||||
if (hoistedScripts.size) {
|
||||
for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) {
|
||||
if (isPropagatedAsset(parentInfo.id)) {
|
||||
if (!internals.propagatedScriptsMap.has(parentInfo.id)) {
|
||||
internals.propagatedScriptsMap.set(parentInfo.id, /* @__PURE__ */ new Set());
|
||||
}
|
||||
const propagatedScripts = internals.propagatedScriptsMap.get(parentInfo.id);
|
||||
for (const hid of hoistedScripts) {
|
||||
propagatedScripts.add(hid);
|
||||
}
|
||||
} else if (moduleIsTopLevelPage(parentInfo)) {
|
||||
if (!pageScriptsMap.has(parentInfo.id)) {
|
||||
pageScriptsMap.set(parentInfo.id, {
|
||||
hoistedSet: /* @__PURE__ */ new Set()
|
||||
});
|
||||
}
|
||||
const pageScripts = pageScriptsMap.get(parentInfo.id);
|
||||
for (const hid of hoistedScripts) {
|
||||
pageScripts.hoistedSet.add(hid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
finalize() {
|
||||
for (const propagatedScripts of internals.propagatedScriptsMap.values()) {
|
||||
for (const propagatedScript of propagatedScripts) {
|
||||
internals.discoveredScripts.add(propagatedScript);
|
||||
}
|
||||
}
|
||||
for (const [pageId, { hoistedSet }] of pageScriptsMap) {
|
||||
const pageData = getPageDataByViteID(internals, pageId);
|
||||
if (!pageData) continue;
|
||||
const { component } = pageData;
|
||||
const astroModuleId = prependForwardSlash(component);
|
||||
const uniqueHoistedId = JSON.stringify(Array.from(hoistedSet).sort());
|
||||
let moduleId;
|
||||
if (uniqueHoistedIds.has(uniqueHoistedId)) {
|
||||
moduleId = uniqueHoistedIds.get(uniqueHoistedId);
|
||||
} else {
|
||||
moduleId = `/astro/hoisted.js?q=${uniqueHoistedIds.size}`;
|
||||
uniqueHoistedIds.set(uniqueHoistedId, moduleId);
|
||||
}
|
||||
internals.discoveredScripts.add(moduleId);
|
||||
if (internals.hoistedScriptIdToPagesMap.has(moduleId)) {
|
||||
const pages = internals.hoistedScriptIdToPagesMap.get(moduleId);
|
||||
pages.add(astroModuleId);
|
||||
} else {
|
||||
internals.hoistedScriptIdToPagesMap.set(moduleId, /* @__PURE__ */ new Set([astroModuleId]));
|
||||
internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
name: "@astro/rollup-plugin-astro-analyzer",
|
||||
async generateBundle() {
|
||||
const hoistScanner = options.settings.config.experimental.directRenderScript ? { scan: async () => {
|
||||
}, finalize: () => {
|
||||
} } : hoistedScriptScanner();
|
||||
const ids = this.getModuleIds();
|
||||
for (const id of ids) {
|
||||
const info = this.getModuleInfo(id);
|
||||
if (!info?.meta?.astro) continue;
|
||||
const astro = info.meta.astro;
|
||||
for (const c of astro.hydratedComponents) {
|
||||
const rid = c.resolvedPath ? decodeURI(c.resolvedPath) : c.specifier;
|
||||
if (internals.discoveredHydratedComponents.has(rid)) {
|
||||
const exportNames = internals.discoveredHydratedComponents.get(rid);
|
||||
exportNames?.push(c.exportName);
|
||||
} else {
|
||||
internals.discoveredHydratedComponents.set(rid, [c.exportName]);
|
||||
}
|
||||
}
|
||||
await hoistScanner.scan.call(this, astro.scripts, id);
|
||||
if (astro.clientOnlyComponents.length) {
|
||||
const clientOnlys = [];
|
||||
for (const c of astro.clientOnlyComponents) {
|
||||
const cid = c.resolvedPath ? decodeURI(c.resolvedPath) : c.specifier;
|
||||
if (internals.discoveredClientOnlyComponents.has(cid)) {
|
||||
const exportNames = internals.discoveredClientOnlyComponents.get(cid);
|
||||
exportNames?.push(c.exportName);
|
||||
} else {
|
||||
internals.discoveredClientOnlyComponents.set(cid, [c.exportName]);
|
||||
}
|
||||
clientOnlys.push(cid);
|
||||
const resolvedId = await this.resolve(c.specifier, id);
|
||||
if (resolvedId) {
|
||||
clientOnlys.push(resolvedId.id);
|
||||
}
|
||||
}
|
||||
for (const pageInfo of getTopLevelPageModuleInfos(id, this)) {
|
||||
const newPageData = getPageDataByViteID(internals, pageInfo.id);
|
||||
if (!newPageData) continue;
|
||||
trackClientOnlyPageDatas(internals, newPageData, clientOnlys);
|
||||
}
|
||||
}
|
||||
if (options.settings.config.experimental.directRenderScript && astro.scripts.length) {
|
||||
const scriptIds = astro.scripts.map(
|
||||
(_, i) => `${id.replace("/@fs", "")}?astro&type=script&index=${i}&lang.ts`
|
||||
);
|
||||
for (const scriptId of scriptIds) {
|
||||
internals.discoveredScripts.add(scriptId);
|
||||
}
|
||||
for (const pageInfo of getTopLevelPageModuleInfos(id, this)) {
|
||||
const newPageData = getPageDataByViteID(internals, pageInfo.id);
|
||||
if (!newPageData) continue;
|
||||
trackScriptPageDatas(internals, newPageData, scriptIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
hoistScanner.finalize();
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginAnalyzer(options, internals) {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginAnalyzer(options, internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginAnalyzer,
|
||||
vitePluginAnalyzer
|
||||
};
|
4
node_modules/astro/dist/core/build/plugins/plugin-chunks.d.ts
generated
vendored
Normal file
4
node_modules/astro/dist/core/build/plugins/plugin-chunks.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
export declare function vitePluginChunks(): VitePlugin;
|
||||
export declare function pluginChunks(): AstroBuildPlugin;
|
37
node_modules/astro/dist/core/build/plugins/plugin-chunks.js
generated
vendored
Normal file
37
node_modules/astro/dist/core/build/plugins/plugin-chunks.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import { extendManualChunks } from "./util.js";
|
||||
function vitePluginChunks() {
|
||||
return {
|
||||
name: "astro:chunks",
|
||||
outputOptions(outputOptions) {
|
||||
extendManualChunks(outputOptions, {
|
||||
after(id) {
|
||||
if (id.includes("astro/dist/runtime/server/")) {
|
||||
return "astro/server";
|
||||
}
|
||||
if (id.includes("astro/dist/runtime")) {
|
||||
return "astro";
|
||||
}
|
||||
if (id.includes("astro/dist/env/setup")) {
|
||||
return "astro/env-setup";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginChunks() {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginChunks()
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginChunks,
|
||||
vitePluginChunks
|
||||
};
|
12
node_modules/astro/dist/core/build/plugins/plugin-component-entry.d.ts
generated
vendored
Normal file
12
node_modules/astro/dist/core/build/plugins/plugin-component-entry.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
export declare const astroEntryPrefix = "\0astro-entry:";
|
||||
/**
|
||||
* When adding hydrated or client:only components as Rollup inputs, sometimes we're not using all
|
||||
* of the export names, e.g. `import { Counter } from './ManyComponents.jsx'`. This plugin proxies
|
||||
* entries to re-export only the names the user is using.
|
||||
*/
|
||||
export declare function vitePluginComponentEntry(internals: BuildInternals): VitePlugin;
|
||||
export declare function normalizeEntryId(id: string): string;
|
||||
export declare function pluginComponentEntry(internals: BuildInternals): AstroBuildPlugin;
|
73
node_modules/astro/dist/core/build/plugins/plugin-component-entry.js
generated
vendored
Normal file
73
node_modules/astro/dist/core/build/plugins/plugin-component-entry.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
const astroEntryPrefix = "\0astro-entry:";
|
||||
function vitePluginComponentEntry(internals) {
|
||||
const componentToExportNames = /* @__PURE__ */ new Map();
|
||||
mergeComponentExportNames(internals.discoveredHydratedComponents);
|
||||
mergeComponentExportNames(internals.discoveredClientOnlyComponents);
|
||||
for (const [componentId, exportNames] of componentToExportNames) {
|
||||
if (exportNames.some((name) => name.includes(".") || name === "*")) {
|
||||
componentToExportNames.delete(componentId);
|
||||
} else {
|
||||
componentToExportNames.set(componentId, Array.from(new Set(exportNames)));
|
||||
}
|
||||
}
|
||||
function mergeComponentExportNames(components) {
|
||||
for (const [componentId, exportNames] of components) {
|
||||
if (componentToExportNames.has(componentId)) {
|
||||
componentToExportNames.get(componentId)?.push(...exportNames);
|
||||
} else {
|
||||
componentToExportNames.set(componentId, exportNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: "@astro/plugin-component-entry",
|
||||
enforce: "pre",
|
||||
config(config) {
|
||||
const rollupInput = config.build?.rollupOptions?.input;
|
||||
if (Array.isArray(rollupInput)) {
|
||||
config.build.rollupOptions.input = rollupInput.map((id) => {
|
||||
if (componentToExportNames.has(id)) {
|
||||
return astroEntryPrefix + id;
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
async resolveId(id) {
|
||||
if (id.startsWith(astroEntryPrefix)) {
|
||||
return id;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id.startsWith(astroEntryPrefix)) {
|
||||
const componentId = id.slice(astroEntryPrefix.length);
|
||||
const exportNames = componentToExportNames.get(componentId);
|
||||
if (exportNames) {
|
||||
return `export { ${exportNames.join(", ")} } from ${JSON.stringify(componentId)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function normalizeEntryId(id) {
|
||||
return id.startsWith(astroEntryPrefix) ? id.slice(astroEntryPrefix.length) : id;
|
||||
}
|
||||
function pluginComponentEntry(internals) {
|
||||
return {
|
||||
targets: ["client"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginComponentEntry(internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
astroEntryPrefix,
|
||||
normalizeEntryId,
|
||||
pluginComponentEntry,
|
||||
vitePluginComponentEntry
|
||||
};
|
5
node_modules/astro/dist/core/build/plugins/plugin-content.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/build/plugins/plugin-content.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare function copyContentToCache(opts: StaticBuildOptions): Promise<string[]>;
|
||||
export declare function pluginContent(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
394
node_modules/astro/dist/core/build/plugins/plugin-content.js
generated
vendored
Normal file
394
node_modules/astro/dist/core/build/plugins/plugin-content.js
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import fsMod from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import glob from "fast-glob";
|
||||
import pLimit from "p-limit";
|
||||
import { normalizePath } from "vite";
|
||||
import { CONTENT_RENDER_FLAG, PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
|
||||
import { hasContentFlag } from "../../../content/utils.js";
|
||||
import {
|
||||
generateContentEntryFile,
|
||||
generateLookupMap
|
||||
} from "../../../content/vite-plugin-content-virtual-mod.js";
|
||||
import { configPaths } from "../../config/index.js";
|
||||
import { emptyDir } from "../../fs/index.js";
|
||||
import {
|
||||
appendForwardSlash,
|
||||
joinPaths,
|
||||
removeFileExtension,
|
||||
removeLeadingForwardSlash
|
||||
} from "../../path.js";
|
||||
import { isContentCollectionsCacheEnabled } from "../../util.js";
|
||||
import { addRollupInput } from "../add-rollup-input.js";
|
||||
import { CHUNKS_PATH, CONTENT_PATH } from "../consts.js";
|
||||
import { copyFiles } from "../static-build.js";
|
||||
import { encodeName } from "../util.js";
|
||||
import { extendManualChunks } from "./util.js";
|
||||
const CONTENT_CACHE_DIR = "./" + CONTENT_PATH;
|
||||
const CONTENT_MANIFEST_FILE = "./manifest.json";
|
||||
const CONTENT_MANIFEST_VERSION = 1;
|
||||
const virtualEmptyModuleId = `virtual:empty-content`;
|
||||
const resolvedVirtualEmptyModuleId = `\0${virtualEmptyModuleId}`;
|
||||
const NO_MANIFEST_VERSION = -1;
|
||||
function createContentManifest() {
|
||||
return {
|
||||
version: NO_MANIFEST_VERSION,
|
||||
entries: [],
|
||||
serverEntries: [],
|
||||
clientEntries: [],
|
||||
lockfiles: "",
|
||||
configs: ""
|
||||
};
|
||||
}
|
||||
const getContentRoot = (config) => new URL("./content/", config.outDir);
|
||||
const getContentCacheDir = (config) => new URL(CONTENT_CACHE_DIR, config.cacheDir);
|
||||
const getCacheTmp = (contentCacheDir) => new URL("./.tmp/", contentCacheDir);
|
||||
function vitePluginContent(opts, lookupMap, internals, cachedBuildOutput) {
|
||||
const { config } = opts.settings;
|
||||
const distContentRoot = getContentRoot(config);
|
||||
const contentCacheDir = getContentCacheDir(config);
|
||||
const contentManifestFile = new URL(CONTENT_MANIFEST_FILE, contentCacheDir);
|
||||
let oldManifest = createContentManifest();
|
||||
let newManifest = createContentManifest();
|
||||
let entries;
|
||||
let injectedEmptyFile = false;
|
||||
let currentManifestState = "valid";
|
||||
if (fsMod.existsSync(contentManifestFile)) {
|
||||
try {
|
||||
const data = fsMod.readFileSync(contentManifestFile, { encoding: "utf8" });
|
||||
oldManifest = JSON.parse(data);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: "@astro/plugin-build-content",
|
||||
async options(options) {
|
||||
let newOptions = Object.assign({}, options);
|
||||
newManifest = await generateContentManifest(opts, lookupMap);
|
||||
entries = getEntriesFromManifests(oldManifest, newManifest);
|
||||
currentManifestState = manifestState(oldManifest, newManifest);
|
||||
if (currentManifestState === "valid") {
|
||||
internals.cachedClientEntries = oldManifest.clientEntries;
|
||||
} else {
|
||||
let logReason = "";
|
||||
switch (currentManifestState) {
|
||||
case "config-mismatch":
|
||||
logReason = "Astro config has changed";
|
||||
break;
|
||||
case "lockfile-mismatch":
|
||||
logReason = "Lockfiles have changed";
|
||||
break;
|
||||
case "no-entries":
|
||||
logReason = "No content collections entries cached";
|
||||
break;
|
||||
case "version-mismatch":
|
||||
logReason = "The cache manifest version has changed";
|
||||
break;
|
||||
case "no-manifest":
|
||||
logReason = "No content manifest was found in the cache";
|
||||
break;
|
||||
}
|
||||
opts.logger.info("build", `Cache invalid, rebuilding from source. Reason: ${logReason}.`);
|
||||
}
|
||||
for (const { type, entry } of entries.buildFromSource) {
|
||||
const fileURL = encodeURI(joinPaths(opts.settings.config.root.toString(), entry));
|
||||
const input = fileURLToPath(fileURL);
|
||||
const inputs = [`${input}?${collectionTypeToFlag(type)}`];
|
||||
if (type === "content") {
|
||||
inputs.push(`${input}?${CONTENT_RENDER_FLAG}`);
|
||||
}
|
||||
newOptions = addRollupInput(newOptions, inputs);
|
||||
}
|
||||
if (currentManifestState === "valid") {
|
||||
for (const { cached, dist } of cachedBuildOutput) {
|
||||
if (fsMod.existsSync(cached)) {
|
||||
await copyFiles(cached, dist, true);
|
||||
}
|
||||
}
|
||||
const cacheExists = fsMod.existsSync(contentCacheDir);
|
||||
if (cacheExists) {
|
||||
await copyFiles(contentCacheDir, distContentRoot, false);
|
||||
}
|
||||
}
|
||||
if (entries.buildFromSource.length === 0) {
|
||||
newOptions = addRollupInput(newOptions, [virtualEmptyModuleId]);
|
||||
injectedEmptyFile = true;
|
||||
}
|
||||
return newOptions;
|
||||
},
|
||||
outputOptions(outputOptions) {
|
||||
const rootPath = normalizePath(fileURLToPath(opts.settings.config.root));
|
||||
const srcPath = normalizePath(fileURLToPath(opts.settings.config.srcDir));
|
||||
const entryCache = /* @__PURE__ */ new Map();
|
||||
extendManualChunks(outputOptions, {
|
||||
before(id, meta) {
|
||||
if (id.startsWith(srcPath) && id.slice(srcPath.length).startsWith("content")) {
|
||||
const info = meta.getModuleInfo(id);
|
||||
if (info?.dynamicImporters.length === 1 && hasContentFlag(info.dynamicImporters[0], PROPAGATED_ASSET_FLAG)) {
|
||||
const [srcRelativePath2] = id.replace(rootPath, "/").split("?");
|
||||
const resultId = encodeName(
|
||||
`${removeLeadingForwardSlash(removeFileExtension(srcRelativePath2))}.render.mjs`
|
||||
);
|
||||
return resultId;
|
||||
}
|
||||
const [srcRelativePath, flag] = id.replace(rootPath, "/").split("?");
|
||||
const collectionEntry = findEntryFromSrcRelativePath(
|
||||
lookupMap,
|
||||
srcRelativePath,
|
||||
entryCache
|
||||
);
|
||||
if (collectionEntry) {
|
||||
let suffix = ".mjs";
|
||||
if (flag === PROPAGATED_ASSET_FLAG) {
|
||||
suffix = ".entry.mjs";
|
||||
}
|
||||
id = removeLeadingForwardSlash(
|
||||
removeFileExtension(encodeName(id.replace(srcPath, "/")))
|
||||
) + suffix;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id === virtualEmptyModuleId) {
|
||||
return resolvedVirtualEmptyModuleId;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === resolvedVirtualEmptyModuleId) {
|
||||
return {
|
||||
code: `// intentionally left empty!
|
||||
export default {}`
|
||||
};
|
||||
}
|
||||
},
|
||||
async generateBundle(_options, bundle) {
|
||||
const code = await generateContentEntryFile({
|
||||
settings: opts.settings,
|
||||
fs: fsMod,
|
||||
lookupMap,
|
||||
IS_DEV: false,
|
||||
IS_SERVER: false,
|
||||
isClient: false
|
||||
});
|
||||
this.emitFile({
|
||||
type: "prebuilt-chunk",
|
||||
code,
|
||||
fileName: "content/entry.mjs"
|
||||
});
|
||||
if (!injectedEmptyFile) return;
|
||||
Object.keys(bundle).forEach((key) => {
|
||||
const mod = bundle[key];
|
||||
if (mod.type === "asset") return;
|
||||
if (mod.facadeModuleId === resolvedVirtualEmptyModuleId) {
|
||||
delete bundle[key];
|
||||
}
|
||||
});
|
||||
},
|
||||
async writeBundle() {
|
||||
const clientComponents = /* @__PURE__ */ new Set([
|
||||
...oldManifest.clientEntries,
|
||||
...internals.discoveredHydratedComponents.keys(),
|
||||
...internals.discoveredClientOnlyComponents.keys(),
|
||||
...internals.discoveredScripts
|
||||
]);
|
||||
const serverComponents = /* @__PURE__ */ new Set([
|
||||
...oldManifest.serverEntries,
|
||||
...internals.discoveredHydratedComponents.keys()
|
||||
]);
|
||||
newManifest.serverEntries = Array.from(serverComponents);
|
||||
newManifest.clientEntries = Array.from(clientComponents);
|
||||
const cacheExists = fsMod.existsSync(contentCacheDir);
|
||||
if (cacheExists && currentManifestState !== "valid") {
|
||||
emptyDir(contentCacheDir);
|
||||
}
|
||||
await fsMod.promises.mkdir(contentCacheDir, { recursive: true });
|
||||
await fsMod.promises.writeFile(contentManifestFile, JSON.stringify(newManifest), {
|
||||
encoding: "utf8"
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
function findEntryFromSrcRelativePath(lookupMap, srcRelativePath, entryCache) {
|
||||
let value = entryCache.get(srcRelativePath);
|
||||
if (value) return value;
|
||||
for (const collection of Object.values(lookupMap)) {
|
||||
for (const entry of Object.values(collection)) {
|
||||
for (const entryFile of Object.values(entry)) {
|
||||
if (entryFile === srcRelativePath) {
|
||||
value = entryFile;
|
||||
entryCache.set(srcRelativePath, entryFile);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function getEntriesFromManifests(oldManifest, newManifest) {
|
||||
const { entries: oldEntries } = oldManifest;
|
||||
const { entries: newEntries } = newManifest;
|
||||
let entries = { restoreFromCache: [], buildFromSource: [] };
|
||||
const newEntryMap = new Map(newEntries);
|
||||
if (manifestState(oldManifest, newManifest) !== "valid") {
|
||||
entries.buildFromSource = Array.from(newEntryMap.keys());
|
||||
return entries;
|
||||
}
|
||||
const oldEntryHashMap = new Map(
|
||||
oldEntries.map(([key, hash]) => [hash, key])
|
||||
);
|
||||
for (const [entry, hash] of newEntryMap) {
|
||||
if (oldEntryHashMap.has(hash)) {
|
||||
entries.restoreFromCache.push(entry);
|
||||
} else {
|
||||
entries.buildFromSource.push(entry);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
function manifestState(oldManifest, newManifest) {
|
||||
if (oldManifest.version === NO_MANIFEST_VERSION) {
|
||||
return "no-manifest";
|
||||
}
|
||||
if (oldManifest.version !== newManifest.version) {
|
||||
return "version-mismatch";
|
||||
}
|
||||
if (oldManifest.entries.length === 0) {
|
||||
return "no-entries";
|
||||
}
|
||||
if (oldManifest.lockfiles !== newManifest.lockfiles || newManifest.lockfiles === "") {
|
||||
return "lockfile-mismatch";
|
||||
}
|
||||
if (oldManifest.configs !== newManifest.configs) {
|
||||
return "config-mismatch";
|
||||
}
|
||||
return "valid";
|
||||
}
|
||||
async function generateContentManifest(opts, lookupMap) {
|
||||
let manifest = createContentManifest();
|
||||
manifest.version = CONTENT_MANIFEST_VERSION;
|
||||
const limit = pLimit(10);
|
||||
const promises = [];
|
||||
for (const [collection, { type, entries }] of Object.entries(lookupMap)) {
|
||||
for (const entry of Object.values(entries)) {
|
||||
const key = { collection, type, entry };
|
||||
const fileURL = new URL(encodeURI(joinPaths(opts.settings.config.root.toString(), entry)));
|
||||
promises.push(
|
||||
limit(async () => {
|
||||
const data = await fsMod.promises.readFile(fileURL, { encoding: "utf8" });
|
||||
manifest.entries.push([key, checksum(data, fileURL.toString())]);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
const [lockfiles, configs] = await Promise.all([
|
||||
lockfilesHash(opts.settings.config.root),
|
||||
configHash(opts.settings.config.root)
|
||||
]);
|
||||
manifest.lockfiles = lockfiles;
|
||||
manifest.configs = configs;
|
||||
await Promise.all(promises);
|
||||
return manifest;
|
||||
}
|
||||
async function pushBufferInto(fileURL, buffers) {
|
||||
try {
|
||||
const handle = await fsMod.promises.open(fileURL, "r");
|
||||
const data = await handle.readFile();
|
||||
buffers.push(data);
|
||||
await handle.close();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
async function lockfilesHash(root) {
|
||||
const lockfiles = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb"];
|
||||
const datas = [];
|
||||
const promises = [];
|
||||
for (const lockfileName of lockfiles) {
|
||||
const fileURL = new URL(`./${lockfileName}`, root);
|
||||
promises.push(pushBufferInto(fileURL, datas));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
return checksum(...datas);
|
||||
}
|
||||
async function configHash(root) {
|
||||
const configFileNames = configPaths;
|
||||
for (const configPath of configFileNames) {
|
||||
try {
|
||||
const fileURL = new URL(`./${configPath}`, root);
|
||||
const data = await fsMod.promises.readFile(fileURL);
|
||||
const hash = checksum(data);
|
||||
return hash;
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
return checksum(`export default {}`);
|
||||
}
|
||||
function checksum(...datas) {
|
||||
const hash = createHash("sha1");
|
||||
datas.forEach((data) => hash.update(data));
|
||||
return hash.digest("base64");
|
||||
}
|
||||
function collectionTypeToFlag(type) {
|
||||
const name = type[0].toUpperCase() + type.slice(1);
|
||||
return `astro${name}CollectionEntry`;
|
||||
}
|
||||
async function copyContentToCache(opts) {
|
||||
const { config } = opts.settings;
|
||||
const distContentRoot = getContentRoot(config);
|
||||
const contentCacheDir = getContentCacheDir(config);
|
||||
const cacheTmp = getCacheTmp(contentCacheDir);
|
||||
await fsMod.promises.mkdir(cacheTmp, { recursive: true });
|
||||
await copyFiles(distContentRoot, cacheTmp, true);
|
||||
await copyFiles(cacheTmp, contentCacheDir);
|
||||
let files = [];
|
||||
await Promise.all([
|
||||
glob(`**/*.{mjs,json}`, {
|
||||
cwd: fileURLToPath(cacheTmp)
|
||||
}).then((f) => files.push(...f.map((file) => CONTENT_PATH + file))),
|
||||
glob(`**/*.{mjs,json}`, {
|
||||
cwd: fileURLToPath(new URL("./" + CHUNKS_PATH, config.outDir))
|
||||
}).then((f) => files.push(...f.map((file) => CHUNKS_PATH + file)))
|
||||
]);
|
||||
await fsMod.promises.rm(cacheTmp, { recursive: true, force: true });
|
||||
return files;
|
||||
}
|
||||
function pluginContent(opts, internals) {
|
||||
const { cacheDir, outDir } = opts.settings.config;
|
||||
const chunksFolder = "./" + CHUNKS_PATH;
|
||||
const assetsFolder = "./" + appendForwardSlash(opts.settings.config.build.assets);
|
||||
const cachedBuildOutput = [
|
||||
{ cached: new URL(chunksFolder, cacheDir), dist: new URL(chunksFolder, outDir) },
|
||||
{ cached: new URL(assetsFolder, cacheDir), dist: new URL(assetsFolder, outDir) }
|
||||
];
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
async "build:before"() {
|
||||
if (!isContentCollectionsCacheEnabled(opts.settings.config)) {
|
||||
return { vitePlugin: void 0 };
|
||||
}
|
||||
const lookupMap = await generateLookupMap({ settings: opts.settings, fs: fsMod });
|
||||
return {
|
||||
vitePlugin: vitePluginContent(opts, lookupMap, internals, cachedBuildOutput)
|
||||
};
|
||||
},
|
||||
async "build:post"() {
|
||||
if (!isContentCollectionsCacheEnabled(opts.settings.config)) {
|
||||
return;
|
||||
}
|
||||
const promises = [];
|
||||
for (const { cached, dist } of cachedBuildOutput) {
|
||||
if (fsMod.existsSync(dist)) {
|
||||
promises.push(copyFiles(dist, cached, true));
|
||||
}
|
||||
}
|
||||
if (promises.length) await Promise.all(promises);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
copyContentToCache,
|
||||
pluginContent
|
||||
};
|
5
node_modules/astro/dist/core/build/plugins/plugin-css.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/build/plugins/plugin-css.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
/***** ASTRO PLUGIN *****/
|
||||
export declare function pluginCSS(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
230
node_modules/astro/dist/core/build/plugins/plugin-css.js
generated
vendored
Normal file
230
node_modules/astro/dist/core/build/plugins/plugin-css.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
import { isBuildableCSSRequest } from "../../../vite-plugin-astro-server/util.js";
|
||||
import { hasAssetPropagationFlag } from "../../../content/index.js";
|
||||
import * as assetName from "../css-asset-name.js";
|
||||
import {
|
||||
getParentExtendedModuleInfos,
|
||||
getParentModuleInfos,
|
||||
moduleIsTopLevelPage
|
||||
} from "../graph.js";
|
||||
import {
|
||||
getPageDataByViteID,
|
||||
getPageDatasByClientOnlyID,
|
||||
getPageDatasByHoistedScriptId
|
||||
} from "../internal.js";
|
||||
import { extendManualChunks, shouldInlineAsset } from "./util.js";
|
||||
function pluginCSS(options, internals) {
|
||||
return {
|
||||
targets: ["client", "server"],
|
||||
hooks: {
|
||||
"build:before": ({ target }) => {
|
||||
let plugins = rollupPluginAstroBuildCSS({
|
||||
buildOptions: options,
|
||||
internals,
|
||||
target
|
||||
});
|
||||
return {
|
||||
vitePlugin: plugins
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function rollupPluginAstroBuildCSS(options) {
|
||||
const { internals, buildOptions } = options;
|
||||
const { settings } = buildOptions;
|
||||
let resolvedConfig;
|
||||
const pagesToCss = {};
|
||||
const moduleIdToPropagatedCss = {};
|
||||
const cssBuildPlugin = {
|
||||
name: "astro:rollup-plugin-build-css",
|
||||
outputOptions(outputOptions) {
|
||||
const assetFileNames = outputOptions.assetFileNames;
|
||||
const namingIncludesHash = assetFileNames?.toString().includes("[hash]");
|
||||
const createNameForParentPages = namingIncludesHash ? assetName.shortHashedName(settings) : assetName.createSlugger(settings);
|
||||
extendManualChunks(outputOptions, {
|
||||
after(id, meta) {
|
||||
if (isBuildableCSSRequest(id)) {
|
||||
if (options.target === "client") {
|
||||
return internals.cssModuleToChunkIdMap.get(id);
|
||||
}
|
||||
const ctx = { getModuleInfo: meta.getModuleInfo };
|
||||
for (const pageInfo of getParentModuleInfos(id, ctx)) {
|
||||
if (hasAssetPropagationFlag(pageInfo.id)) {
|
||||
const chunkId2 = assetName.createNameHash(id, [id], settings);
|
||||
internals.cssModuleToChunkIdMap.set(id, chunkId2);
|
||||
return chunkId2;
|
||||
}
|
||||
}
|
||||
const chunkId = createNameForParentPages(id, meta);
|
||||
internals.cssModuleToChunkIdMap.set(id, chunkId);
|
||||
return chunkId;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
async generateBundle(_outputOptions, bundle) {
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type !== "chunk") continue;
|
||||
if ("viteMetadata" in chunk === false) continue;
|
||||
const meta = chunk.viteMetadata;
|
||||
if (meta.importedCss.size < 1) continue;
|
||||
if (options.target === "client") {
|
||||
for (const id of Object.keys(chunk.modules)) {
|
||||
for (const pageData of getParentClientOnlys(id, this, internals)) {
|
||||
for (const importedCssImport of meta.importedCss) {
|
||||
const cssToInfoRecord = pagesToCss[pageData.moduleSpecifier] ??= {};
|
||||
cssToInfoRecord[importedCssImport] = { depth: -1, order: -1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const id of Object.keys(chunk.modules)) {
|
||||
const parentModuleInfos = getParentExtendedModuleInfos(id, this, hasAssetPropagationFlag);
|
||||
for (const { info: pageInfo, depth, order } of parentModuleInfos) {
|
||||
if (hasAssetPropagationFlag(pageInfo.id)) {
|
||||
const propagatedCss = moduleIdToPropagatedCss[pageInfo.id] ??= /* @__PURE__ */ new Set();
|
||||
for (const css of meta.importedCss) {
|
||||
propagatedCss.add(css);
|
||||
}
|
||||
} else if (moduleIsTopLevelPage(pageInfo)) {
|
||||
const pageViteID = pageInfo.id;
|
||||
const pageData = getPageDataByViteID(internals, pageViteID);
|
||||
if (pageData) {
|
||||
appendCSSToPage(pageData, meta, pagesToCss, depth, order);
|
||||
}
|
||||
} else if (options.target === "client") {
|
||||
if (buildOptions.settings.config.experimental.directRenderScript) {
|
||||
const pageDatas = internals.pagesByScriptId.get(pageInfo.id);
|
||||
if (pageDatas) {
|
||||
for (const pageData of pageDatas) {
|
||||
appendCSSToPage(pageData, meta, pagesToCss, -1, order);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (internals.hoistedScriptIdToPagesMap.has(pageInfo.id)) {
|
||||
for (const pageData of getPageDatasByHoistedScriptId(internals, pageInfo.id)) {
|
||||
appendCSSToPage(pageData, meta, pagesToCss, -1, order);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const cssScopeToPlugin = {
|
||||
name: "astro:rollup-plugin-css-scope-to",
|
||||
renderChunk(_, chunk, __, meta) {
|
||||
for (const id in chunk.modules) {
|
||||
const modMeta = this.getModuleInfo(id)?.meta;
|
||||
const cssScopeTo = modMeta?.astroCss?.cssScopeTo;
|
||||
if (cssScopeTo && !isCssScopeToRendered(cssScopeTo, Object.values(meta.chunks))) {
|
||||
delete chunk.modules[id];
|
||||
const moduleIdsIndex = chunk.moduleIds.indexOf(id);
|
||||
if (moduleIdsIndex > -1) {
|
||||
chunk.moduleIds.splice(moduleIdsIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const singleCssPlugin = {
|
||||
name: "astro:rollup-plugin-single-css",
|
||||
enforce: "post",
|
||||
configResolved(config) {
|
||||
resolvedConfig = config;
|
||||
},
|
||||
generateBundle(_, bundle) {
|
||||
if (resolvedConfig.build.cssCodeSplit) return;
|
||||
const cssChunk = Object.values(bundle).find(
|
||||
(chunk) => chunk.type === "asset" && chunk.name === "style.css"
|
||||
);
|
||||
if (cssChunk === void 0) return;
|
||||
for (const pageData of internals.pagesByKeys.values()) {
|
||||
const cssToInfoMap = pagesToCss[pageData.moduleSpecifier] ??= {};
|
||||
cssToInfoMap[cssChunk.fileName] = { depth: -1, order: -1 };
|
||||
}
|
||||
}
|
||||
};
|
||||
let assetsInlineLimit;
|
||||
const inlineStylesheetsPlugin = {
|
||||
name: "astro:rollup-plugin-inline-stylesheets",
|
||||
enforce: "post",
|
||||
configResolved(config) {
|
||||
assetsInlineLimit = config.build.assetsInlineLimit;
|
||||
},
|
||||
async generateBundle(_outputOptions, bundle) {
|
||||
const inlineConfig = settings.config.build.inlineStylesheets;
|
||||
Object.entries(bundle).forEach(([id, stylesheet]) => {
|
||||
if (stylesheet.type !== "asset" || stylesheet.name?.endsWith(".css") !== true || typeof stylesheet.source !== "string")
|
||||
return;
|
||||
const toBeInlined = inlineConfig === "always" ? true : inlineConfig === "never" ? false : shouldInlineAsset(stylesheet.source, stylesheet.fileName, assetsInlineLimit);
|
||||
const sheet = toBeInlined ? { type: "inline", content: stylesheet.source } : { type: "external", src: stylesheet.fileName };
|
||||
let sheetAddedToPage = false;
|
||||
internals.pagesByKeys.forEach((pageData) => {
|
||||
const orderingInfo = pagesToCss[pageData.moduleSpecifier]?.[stylesheet.fileName];
|
||||
if (orderingInfo !== void 0) {
|
||||
pageData.styles.push({ ...orderingInfo, sheet });
|
||||
sheetAddedToPage = true;
|
||||
}
|
||||
});
|
||||
for (const moduleId in moduleIdToPropagatedCss) {
|
||||
if (!moduleIdToPropagatedCss[moduleId].has(stylesheet.fileName)) continue;
|
||||
let propagatedStyles = internals.propagatedStylesMap.get(moduleId);
|
||||
if (!propagatedStyles) {
|
||||
propagatedStyles = /* @__PURE__ */ new Set();
|
||||
internals.propagatedStylesMap.set(moduleId, propagatedStyles);
|
||||
}
|
||||
propagatedStyles.add(sheet);
|
||||
sheetAddedToPage = true;
|
||||
}
|
||||
if (toBeInlined && sheetAddedToPage) {
|
||||
delete bundle[id];
|
||||
for (const chunk of Object.values(bundle)) {
|
||||
if (chunk.type === "chunk") {
|
||||
chunk.viteMetadata?.importedCss?.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return [cssBuildPlugin, cssScopeToPlugin, singleCssPlugin, inlineStylesheetsPlugin];
|
||||
}
|
||||
function* getParentClientOnlys(id, ctx, internals) {
|
||||
for (const info of getParentModuleInfos(id, ctx)) {
|
||||
yield* getPageDatasByClientOnlyID(internals, info.id);
|
||||
}
|
||||
}
|
||||
function appendCSSToPage(pageData, meta, pagesToCss, depth, order) {
|
||||
for (const importedCssImport of meta.importedCss) {
|
||||
const cssInfo = pagesToCss[pageData.moduleSpecifier]?.[importedCssImport];
|
||||
if (cssInfo !== void 0) {
|
||||
if (depth < cssInfo.depth) {
|
||||
cssInfo.depth = depth;
|
||||
}
|
||||
if (cssInfo.order === -1) {
|
||||
cssInfo.order = order;
|
||||
} else if (order < cssInfo.order && order > -1) {
|
||||
cssInfo.order = order;
|
||||
}
|
||||
} else {
|
||||
const cssToInfoRecord = pagesToCss[pageData.moduleSpecifier] ??= {};
|
||||
cssToInfoRecord[importedCssImport] = { depth, order };
|
||||
}
|
||||
}
|
||||
}
|
||||
function isCssScopeToRendered(cssScopeTo, chunks) {
|
||||
for (const moduleId in cssScopeTo) {
|
||||
const exports = cssScopeTo[moduleId];
|
||||
const renderedModule = chunks.find((c) => c.moduleIds.includes(moduleId))?.modules[moduleId];
|
||||
if (renderedModule?.renderedExports.some((e) => exports.includes(e))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export {
|
||||
pluginCSS
|
||||
};
|
5
node_modules/astro/dist/core/build/plugins/plugin-hoisted-scripts.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/build/plugins/plugin-hoisted-scripts.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
export declare function vitePluginHoistedScripts(internals: BuildInternals): VitePlugin;
|
||||
export declare function pluginHoistedScripts(internals: BuildInternals): AstroBuildPlugin;
|
83
node_modules/astro/dist/core/build/plugins/plugin-hoisted-scripts.js
generated
vendored
Normal file
83
node_modules/astro/dist/core/build/plugins/plugin-hoisted-scripts.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import { getPageDatasByHoistedScriptId } from "../internal.js";
|
||||
import { shouldInlineAsset } from "./util.js";
|
||||
function virtualHoistedEntry(id) {
|
||||
return id.startsWith("/astro/hoisted.js?q=");
|
||||
}
|
||||
function vitePluginHoistedScripts(internals) {
|
||||
let assetsInlineLimit;
|
||||
return {
|
||||
name: "@astro/rollup-plugin-astro-hoisted-scripts",
|
||||
configResolved(config) {
|
||||
assetsInlineLimit = config.build.assetsInlineLimit;
|
||||
},
|
||||
resolveId(id) {
|
||||
if (virtualHoistedEntry(id)) {
|
||||
return id;
|
||||
}
|
||||
},
|
||||
load(id) {
|
||||
if (virtualHoistedEntry(id)) {
|
||||
let code = "";
|
||||
for (let path of internals.hoistedScriptIdToHoistedMap.get(id)) {
|
||||
let importPath = path;
|
||||
if (importPath.startsWith("/@fs")) {
|
||||
importPath = importPath.slice("/@fs".length);
|
||||
}
|
||||
code += `import "${importPath}";`;
|
||||
}
|
||||
return {
|
||||
code
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
},
|
||||
async generateBundle(_options, bundle) {
|
||||
const considerInlining = /* @__PURE__ */ new Map();
|
||||
const importedByOtherScripts = /* @__PURE__ */ new Set();
|
||||
Object.entries(bundle).forEach(([id, output]) => {
|
||||
if (output.type === "chunk" && output.facadeModuleId && virtualHoistedEntry(output.facadeModuleId)) {
|
||||
considerInlining.set(id, output);
|
||||
output.imports.forEach((imported) => importedByOtherScripts.add(imported));
|
||||
}
|
||||
});
|
||||
for (const [id, output] of considerInlining.entries()) {
|
||||
const canBeInlined = importedByOtherScripts.has(output.fileName) === false && output.imports.length === 0 && output.dynamicImports.length === 0 && shouldInlineAsset(output.code, output.fileName, assetsInlineLimit);
|
||||
let removeFromBundle = false;
|
||||
const facadeId = output.facadeModuleId;
|
||||
for (const pageData of getPageDatasByHoistedScriptId(internals, facadeId)) {
|
||||
if (canBeInlined) {
|
||||
pageData.hoistedScript = {
|
||||
type: "inline",
|
||||
value: output.code
|
||||
};
|
||||
removeFromBundle = true;
|
||||
} else {
|
||||
pageData.hoistedScript = {
|
||||
type: "external",
|
||||
value: id
|
||||
};
|
||||
}
|
||||
}
|
||||
if (removeFromBundle) {
|
||||
delete bundle[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginHoistedScripts(internals) {
|
||||
return {
|
||||
targets: ["client"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginHoistedScripts(internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginHoistedScripts,
|
||||
vitePluginHoistedScripts
|
||||
};
|
5
node_modules/astro/dist/core/build/plugins/plugin-internals.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/build/plugins/plugin-internals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
export declare function vitePluginInternals(input: Set<string>, internals: BuildInternals): VitePlugin;
|
||||
export declare function pluginInternals(internals: BuildInternals): AstroBuildPlugin;
|
64
node_modules/astro/dist/core/build/plugins/plugin-internals.js
generated
vendored
Normal file
64
node_modules/astro/dist/core/build/plugins/plugin-internals.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
import { normalizeEntryId } from "./plugin-component-entry.js";
|
||||
function vitePluginInternals(input, internals) {
|
||||
return {
|
||||
name: "@astro/plugin-build-internals",
|
||||
config(config, options) {
|
||||
if (options.command === "build" && config.build?.ssr) {
|
||||
return {
|
||||
ssr: {
|
||||
// Always bundle Astro runtime when building for SSR
|
||||
noExternal: ["astro"],
|
||||
// Except for these packages as they're not bundle-friendly. Users with strict package installations
|
||||
// need to manually install these themselves if they use the related features.
|
||||
external: [
|
||||
"sharp"
|
||||
// For sharp image service
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
async generateBundle(_options, bundle) {
|
||||
const promises = [];
|
||||
const mapping = /* @__PURE__ */ new Map();
|
||||
for (const specifier of input) {
|
||||
promises.push(
|
||||
this.resolve(specifier).then((result) => {
|
||||
if (result) {
|
||||
if (mapping.has(result.id)) {
|
||||
mapping.get(result.id).add(specifier);
|
||||
} else {
|
||||
mapping.set(result.id, /* @__PURE__ */ new Set([specifier]));
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "chunk" && chunk.facadeModuleId) {
|
||||
const specifiers = mapping.get(chunk.facadeModuleId) || /* @__PURE__ */ new Set([chunk.facadeModuleId]);
|
||||
for (const specifier of specifiers) {
|
||||
internals.entrySpecifierToBundleMap.set(normalizeEntryId(specifier), chunk.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginInternals(internals) {
|
||||
return {
|
||||
targets: ["client", "server"],
|
||||
hooks: {
|
||||
"build:before": ({ input }) => {
|
||||
return {
|
||||
vitePlugin: vitePluginInternals(input, internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginInternals,
|
||||
vitePluginInternals
|
||||
};
|
6
node_modules/astro/dist/core/build/plugins/plugin-manifest.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/core/build/plugins/plugin-manifest.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { type BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare const SSR_MANIFEST_VIRTUAL_MODULE_ID = "@astrojs-manifest";
|
||||
export declare const RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID: string;
|
||||
export declare function pluginManifest(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
228
node_modules/astro/dist/core/build/plugins/plugin-manifest.js
generated
vendored
Normal file
228
node_modules/astro/dist/core/build/plugins/plugin-manifest.js
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import glob from "fast-glob";
|
||||
import { getAssetsPrefix } from "../../../assets/utils/getAssetsPrefix.js";
|
||||
import { normalizeTheLocale } from "../../../i18n/index.js";
|
||||
import { toFallbackType, toRoutingStrategy } from "../../../i18n/utils.js";
|
||||
import { runHookBuildSsr } from "../../../integrations/hooks.js";
|
||||
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../../vite-plugin-scripts/index.js";
|
||||
import { encodeKey } from "../../encryption.js";
|
||||
import { fileExtension, joinPaths, prependForwardSlash } from "../../path.js";
|
||||
import { serializeRouteData } from "../../routing/index.js";
|
||||
import { addRollupInput } from "../add-rollup-input.js";
|
||||
import { getOutFile, getOutFolder } from "../common.js";
|
||||
import { cssOrder, mergeInlineCss } from "../internal.js";
|
||||
import { makePageDataKey } from "./util.js";
|
||||
const manifestReplace = "@@ASTRO_MANIFEST_REPLACE@@";
|
||||
const replaceExp = new RegExp(`['"]${manifestReplace}['"]`, "g");
|
||||
const SSR_MANIFEST_VIRTUAL_MODULE_ID = "@astrojs-manifest";
|
||||
const RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID = "\0" + SSR_MANIFEST_VIRTUAL_MODULE_ID;
|
||||
function vitePluginManifest(_options, internals) {
|
||||
return {
|
||||
name: "@astro/plugin-build-manifest",
|
||||
enforce: "post",
|
||||
options(opts) {
|
||||
return addRollupInput(opts, [SSR_MANIFEST_VIRTUAL_MODULE_ID]);
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id === SSR_MANIFEST_VIRTUAL_MODULE_ID) {
|
||||
return RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
},
|
||||
augmentChunkHash(chunkInfo) {
|
||||
if (chunkInfo.facadeModuleId === RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID) {
|
||||
return Date.now().toString();
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID) {
|
||||
const imports = [
|
||||
`import { deserializeManifest as _deserializeManifest } from 'astro/app'`,
|
||||
`import { _privateSetManifestDontUseThis } from 'astro:ssr-manifest'`
|
||||
];
|
||||
const contents = [
|
||||
`const manifest = _deserializeManifest('${manifestReplace}');`,
|
||||
`_privateSetManifestDontUseThis(manifest);`
|
||||
];
|
||||
const exports = [`export { manifest }`];
|
||||
return [...imports, ...contents, ...exports].join("\n");
|
||||
}
|
||||
},
|
||||
async generateBundle(_opts, bundle) {
|
||||
for (const [chunkName, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "asset") {
|
||||
continue;
|
||||
}
|
||||
if (chunk.modules[RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID]) {
|
||||
internals.manifestEntryChunk = chunk;
|
||||
delete bundle[chunkName];
|
||||
}
|
||||
if (chunkName.startsWith("manifest")) {
|
||||
internals.manifestFileName = chunkName;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginManifest(options, internals) {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginManifest(options, internals)
|
||||
};
|
||||
},
|
||||
"build:post": async ({ mutate }) => {
|
||||
if (!internals.manifestEntryChunk) {
|
||||
throw new Error(`Did not generate an entry chunk for SSR`);
|
||||
}
|
||||
const manifest = await createManifest(options, internals);
|
||||
const shouldPassMiddlewareEntryPoint = options.settings.adapter?.adapterFeatures?.edgeMiddleware;
|
||||
await runHookBuildSsr({
|
||||
config: options.settings.config,
|
||||
manifest,
|
||||
logger: options.logger,
|
||||
entryPoints: internals.entryPoints,
|
||||
middlewareEntryPoint: shouldPassMiddlewareEntryPoint ? internals.middlewareEntryPoint : void 0
|
||||
});
|
||||
const code = injectManifest(manifest, internals.manifestEntryChunk);
|
||||
mutate(internals.manifestEntryChunk, ["server"], code);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
async function createManifest(buildOpts, internals) {
|
||||
if (!internals.manifestEntryChunk) {
|
||||
throw new Error(`Did not generate an entry chunk for SSR`);
|
||||
}
|
||||
const clientStatics = new Set(
|
||||
await glob("**/*", {
|
||||
cwd: fileURLToPath(buildOpts.settings.config.build.client)
|
||||
})
|
||||
);
|
||||
for (const file of clientStatics) {
|
||||
internals.staticFiles.add(file);
|
||||
}
|
||||
const staticFiles = internals.staticFiles;
|
||||
const encodedKey = await encodeKey(await buildOpts.key);
|
||||
return buildManifest(buildOpts, internals, Array.from(staticFiles), encodedKey);
|
||||
}
|
||||
function injectManifest(manifest, chunk) {
|
||||
const code = chunk.code;
|
||||
return code.replace(replaceExp, () => {
|
||||
return JSON.stringify(manifest);
|
||||
});
|
||||
}
|
||||
function buildManifest(opts, internals, staticFiles, encodedKey) {
|
||||
const { settings } = opts;
|
||||
const routes = [];
|
||||
const domainLookupTable = {};
|
||||
const entryModules = Object.fromEntries(internals.entrySpecifierToBundleMap.entries());
|
||||
if (settings.scripts.some((script) => script.stage === "page")) {
|
||||
staticFiles.push(entryModules[PAGE_SCRIPT_ID]);
|
||||
}
|
||||
const prefixAssetPath = (pth) => {
|
||||
if (settings.config.build.assetsPrefix) {
|
||||
const pf = getAssetsPrefix(fileExtension(pth), settings.config.build.assetsPrefix);
|
||||
return joinPaths(pf, pth);
|
||||
} else {
|
||||
return prependForwardSlash(joinPaths(settings.config.base, pth));
|
||||
}
|
||||
};
|
||||
for (const route of opts.manifest.routes) {
|
||||
if (!route.prerender) continue;
|
||||
if (!route.pathname) continue;
|
||||
const outFolder = getOutFolder(opts.settings.config, route.pathname, route);
|
||||
const outFile = getOutFile(opts.settings.config, outFolder, route.pathname, route);
|
||||
const file = outFile.toString().replace(opts.settings.config.build.client.toString(), "");
|
||||
routes.push({
|
||||
file,
|
||||
links: [],
|
||||
scripts: [],
|
||||
styles: [],
|
||||
routeData: serializeRouteData(route, settings.config.trailingSlash)
|
||||
});
|
||||
staticFiles.push(file);
|
||||
}
|
||||
for (const route of opts.manifest.routes) {
|
||||
const pageData = internals.pagesByKeys.get(makePageDataKey(route.route, route.component));
|
||||
if (route.prerender || !pageData) continue;
|
||||
const scripts = [];
|
||||
if (pageData.hoistedScript) {
|
||||
const shouldPrefixAssetPath = pageData.hoistedScript.type === "external";
|
||||
const hoistedValue = pageData.hoistedScript.value;
|
||||
const value = shouldPrefixAssetPath ? prefixAssetPath(hoistedValue) : hoistedValue;
|
||||
scripts.unshift(
|
||||
Object.assign({}, pageData.hoistedScript, {
|
||||
value
|
||||
})
|
||||
);
|
||||
}
|
||||
if (settings.scripts.some((script) => script.stage === "page")) {
|
||||
const src = entryModules[PAGE_SCRIPT_ID];
|
||||
scripts.push({
|
||||
type: "external",
|
||||
value: prefixAssetPath(src)
|
||||
});
|
||||
}
|
||||
const links = [];
|
||||
const styles = pageData.styles.sort(cssOrder).map(({ sheet }) => sheet).map((s) => s.type === "external" ? { ...s, src: prefixAssetPath(s.src) } : s).reduce(mergeInlineCss, []);
|
||||
routes.push({
|
||||
file: "",
|
||||
links,
|
||||
scripts: [
|
||||
...scripts,
|
||||
...settings.scripts.filter((script) => script.stage === "head-inline").map(({ stage, content }) => ({ stage, children: content }))
|
||||
],
|
||||
styles,
|
||||
routeData: serializeRouteData(route, settings.config.trailingSlash)
|
||||
});
|
||||
}
|
||||
const i18n = settings.config.i18n;
|
||||
if (i18n && i18n.domains) {
|
||||
for (const [locale, domainValue] of Object.entries(i18n.domains)) {
|
||||
domainLookupTable[domainValue] = normalizeTheLocale(locale);
|
||||
}
|
||||
}
|
||||
if (!(BEFORE_HYDRATION_SCRIPT_ID in entryModules)) {
|
||||
entryModules[BEFORE_HYDRATION_SCRIPT_ID] = "";
|
||||
}
|
||||
let i18nManifest = void 0;
|
||||
if (settings.config.i18n) {
|
||||
i18nManifest = {
|
||||
fallback: settings.config.i18n.fallback,
|
||||
fallbackType: toFallbackType(settings.config.i18n.routing),
|
||||
strategy: toRoutingStrategy(settings.config.i18n.routing, settings.config.i18n.domains),
|
||||
locales: settings.config.i18n.locales,
|
||||
defaultLocale: settings.config.i18n.defaultLocale,
|
||||
domainLookupTable
|
||||
};
|
||||
}
|
||||
return {
|
||||
hrefRoot: opts.settings.config.root.toString(),
|
||||
adapterName: opts.settings.adapter?.name ?? "",
|
||||
routes,
|
||||
site: settings.config.site,
|
||||
base: settings.config.base,
|
||||
trailingSlash: settings.config.trailingSlash,
|
||||
compressHTML: settings.config.compressHTML,
|
||||
assetsPrefix: settings.config.build.assetsPrefix,
|
||||
componentMetadata: Array.from(internals.componentMetadata),
|
||||
renderers: [],
|
||||
clientDirectives: Array.from(settings.clientDirectives),
|
||||
entryModules,
|
||||
inlinedScripts: Array.from(internals.inlinedScripts),
|
||||
assets: staticFiles.map(prefixAssetPath),
|
||||
i18n: i18nManifest,
|
||||
buildFormat: settings.config.build.format,
|
||||
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
||||
serverIslandNameMap: Array.from(settings.serverIslandNameMap),
|
||||
key: encodedKey,
|
||||
experimentalEnvGetSecretEnabled: settings.config.experimental.env !== void 0 && (settings.adapter?.supportedAstroFeatures.envGetSecret ?? "unsupported") !== "unsupported"
|
||||
};
|
||||
}
|
||||
export {
|
||||
RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID,
|
||||
SSR_MANIFEST_VIRTUAL_MODULE_ID,
|
||||
pluginManifest
|
||||
};
|
5
node_modules/astro/dist/core/build/plugins/plugin-middleware.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/build/plugins/plugin-middleware.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export { MIDDLEWARE_MODULE_ID } from '../../middleware/vite-plugin.js';
|
||||
export declare function pluginMiddleware(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
18
node_modules/astro/dist/core/build/plugins/plugin-middleware.js
generated
vendored
Normal file
18
node_modules/astro/dist/core/build/plugins/plugin-middleware.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { vitePluginMiddlewareBuild } from "../../middleware/vite-plugin.js";
|
||||
import { MIDDLEWARE_MODULE_ID } from "../../middleware/vite-plugin.js";
|
||||
function pluginMiddleware(opts, internals) {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginMiddlewareBuild(opts, internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
MIDDLEWARE_MODULE_ID,
|
||||
pluginMiddleware
|
||||
};
|
6
node_modules/astro/dist/core/build/plugins/plugin-pages.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/core/build/plugins/plugin-pages.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare const ASTRO_PAGE_MODULE_ID = "@astro-page:";
|
||||
export declare const ASTRO_PAGE_RESOLVED_MODULE_ID: string;
|
||||
export declare function pluginPages(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
66
node_modules/astro/dist/core/build/plugins/plugin-pages.js
generated
vendored
Normal file
66
node_modules/astro/dist/core/build/plugins/plugin-pages.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
import { routeIsRedirect } from "../../redirects/index.js";
|
||||
import { addRollupInput } from "../add-rollup-input.js";
|
||||
import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
|
||||
import { getPagesFromVirtualModulePageName, getVirtualModulePageName } from "./util.js";
|
||||
const ASTRO_PAGE_MODULE_ID = "@astro-page:";
|
||||
const ASTRO_PAGE_RESOLVED_MODULE_ID = "\0" + ASTRO_PAGE_MODULE_ID;
|
||||
function vitePluginPages(opts, internals) {
|
||||
return {
|
||||
name: "@astro/plugin-build-pages",
|
||||
options(options) {
|
||||
if (opts.settings.config.output === "static") {
|
||||
const inputs = /* @__PURE__ */ new Set();
|
||||
for (const pageData of Object.values(opts.allPages)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
inputs.add(getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component));
|
||||
}
|
||||
return addRollupInput(options, Array.from(inputs));
|
||||
}
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id.startsWith(ASTRO_PAGE_MODULE_ID)) {
|
||||
return "\0" + id;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
|
||||
const imports = [];
|
||||
const exports = [];
|
||||
const pageDatas = getPagesFromVirtualModulePageName(
|
||||
internals,
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
id
|
||||
);
|
||||
for (const pageData of pageDatas) {
|
||||
const resolvedPage = await this.resolve(pageData.moduleSpecifier);
|
||||
if (resolvedPage) {
|
||||
imports.push(`import * as _page from ${JSON.stringify(pageData.moduleSpecifier)};`);
|
||||
exports.push(`export const page = () => _page`);
|
||||
imports.push(`import { renderers } from "${RENDERERS_MODULE_ID}";`);
|
||||
exports.push(`export { renderers };`);
|
||||
return `${imports.join("\n")}${exports.join("\n")}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginPages(opts, internals) {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginPages(opts, internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
ASTRO_PAGE_MODULE_ID,
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
pluginPages
|
||||
};
|
4
node_modules/astro/dist/core/build/plugins/plugin-prerender.d.ts
generated
vendored
Normal file
4
node_modules/astro/dist/core/build/plugins/plugin-prerender.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare function pluginPrerender(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
79
node_modules/astro/dist/core/build/plugins/plugin-prerender.js
generated
vendored
Normal file
79
node_modules/astro/dist/core/build/plugins/plugin-prerender.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
import { getPrerenderMetadata } from "../../../prerender/metadata.js";
|
||||
import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugin-pages.js";
|
||||
import { getPagesFromVirtualModulePageName } from "./util.js";
|
||||
function vitePluginPrerender(internals) {
|
||||
return {
|
||||
name: "astro:rollup-plugin-prerender",
|
||||
generateBundle(_, bundle) {
|
||||
const moduleIds = this.getModuleIds();
|
||||
for (const id of moduleIds) {
|
||||
const pageInfo = internals.pagesByViteID.get(id);
|
||||
if (!pageInfo) continue;
|
||||
const moduleInfo = this.getModuleInfo(id);
|
||||
if (!moduleInfo) continue;
|
||||
const prerender = !!getPrerenderMetadata(moduleInfo);
|
||||
pageInfo.route.prerender = prerender;
|
||||
}
|
||||
const nonPrerenderOnlyChunks = getNonPrerenderOnlyChunks(bundle, internals);
|
||||
internals.prerenderOnlyChunks = Object.values(bundle).filter((chunk) => {
|
||||
return chunk.type === "chunk" && !nonPrerenderOnlyChunks.has(chunk);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
function getNonPrerenderOnlyChunks(bundle, internals) {
|
||||
const chunks = Object.values(bundle);
|
||||
const prerenderOnlyEntryChunks = /* @__PURE__ */ new Set();
|
||||
const nonPrerenderOnlyEntryChunks = /* @__PURE__ */ new Set();
|
||||
for (const chunk of chunks) {
|
||||
if (chunk.type === "chunk" && chunk.isEntry) {
|
||||
if (chunk.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
|
||||
const pageDatas = getPagesFromVirtualModulePageName(
|
||||
internals,
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
chunk.facadeModuleId
|
||||
);
|
||||
const prerender = pageDatas.every((pageData) => pageData.route.prerender);
|
||||
if (prerender) {
|
||||
prerenderOnlyEntryChunks.add(chunk);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
nonPrerenderOnlyEntryChunks.add(chunk);
|
||||
}
|
||||
}
|
||||
const nonPrerenderOnlyChunks = new Set(nonPrerenderOnlyEntryChunks);
|
||||
for (const chunk of nonPrerenderOnlyChunks) {
|
||||
for (const importFileName of chunk.imports) {
|
||||
const importChunk = bundle[importFileName];
|
||||
if (importChunk?.type === "chunk") {
|
||||
nonPrerenderOnlyChunks.add(importChunk);
|
||||
}
|
||||
}
|
||||
for (const dynamicImportFileName of chunk.dynamicImports) {
|
||||
const dynamicImportChunk = bundle[dynamicImportFileName];
|
||||
if (dynamicImportChunk?.type === "chunk" && !prerenderOnlyEntryChunks.has(dynamicImportChunk)) {
|
||||
nonPrerenderOnlyChunks.add(dynamicImportChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nonPrerenderOnlyChunks;
|
||||
}
|
||||
function pluginPrerender(opts, internals) {
|
||||
if (opts.settings.config.output === "static") {
|
||||
return { targets: ["server"] };
|
||||
}
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginPrerender(internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginPrerender
|
||||
};
|
7
node_modules/astro/dist/core/build/plugins/plugin-renderers.d.ts
generated
vendored
Normal file
7
node_modules/astro/dist/core/build/plugins/plugin-renderers.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare const RENDERERS_MODULE_ID = "@astro-renderers";
|
||||
export declare const RESOLVED_RENDERERS_MODULE_ID = "\0@astro-renderers";
|
||||
export declare function vitePluginRenderers(opts: StaticBuildOptions): VitePlugin;
|
||||
export declare function pluginRenderers(opts: StaticBuildOptions): AstroBuildPlugin;
|
55
node_modules/astro/dist/core/build/plugins/plugin-renderers.js
generated
vendored
Normal file
55
node_modules/astro/dist/core/build/plugins/plugin-renderers.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { addRollupInput } from "../add-rollup-input.js";
|
||||
const RENDERERS_MODULE_ID = "@astro-renderers";
|
||||
const RESOLVED_RENDERERS_MODULE_ID = `\0${RENDERERS_MODULE_ID}`;
|
||||
function vitePluginRenderers(opts) {
|
||||
return {
|
||||
name: "@astro/plugin-renderers",
|
||||
options(options) {
|
||||
return addRollupInput(options, [RENDERERS_MODULE_ID]);
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id === RENDERERS_MODULE_ID) {
|
||||
return RESOLVED_RENDERERS_MODULE_ID;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === RESOLVED_RENDERERS_MODULE_ID) {
|
||||
if (opts.settings.renderers.length > 0) {
|
||||
const imports = [];
|
||||
const exports = [];
|
||||
let i = 0;
|
||||
let rendererItems = "";
|
||||
for (const renderer of opts.settings.renderers) {
|
||||
const variable = `_renderer${i}`;
|
||||
imports.push(`import ${variable} from '${renderer.serverEntrypoint}';`);
|
||||
rendererItems += `Object.assign(${JSON.stringify(renderer)}, { ssr: ${variable} }),`;
|
||||
i++;
|
||||
}
|
||||
exports.push(`export const renderers = [${rendererItems}];`);
|
||||
return `${imports.join("\n")}
|
||||
${exports.join("\n")}`;
|
||||
} else {
|
||||
return `export const renderers = [];`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginRenderers(opts) {
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginRenderers(opts)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
RENDERERS_MODULE_ID,
|
||||
RESOLVED_RENDERERS_MODULE_ID,
|
||||
pluginRenderers,
|
||||
vitePluginRenderers
|
||||
};
|
8
node_modules/astro/dist/core/build/plugins/plugin-scripts.d.ts
generated
vendored
Normal file
8
node_modules/astro/dist/core/build/plugins/plugin-scripts.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
/**
|
||||
* Used by the `experimental.directRenderScript` option to inline scripts directly into the HTML.
|
||||
*/
|
||||
export declare function vitePluginScripts(internals: BuildInternals): VitePlugin;
|
||||
export declare function pluginScripts(internals: BuildInternals): AstroBuildPlugin;
|
43
node_modules/astro/dist/core/build/plugins/plugin-scripts.js
generated
vendored
Normal file
43
node_modules/astro/dist/core/build/plugins/plugin-scripts.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import { shouldInlineAsset } from "./util.js";
|
||||
function vitePluginScripts(internals) {
|
||||
let assetInlineLimit;
|
||||
return {
|
||||
name: "@astro/plugin-scripts",
|
||||
configResolved(config) {
|
||||
assetInlineLimit = config.build.assetsInlineLimit;
|
||||
},
|
||||
async generateBundle(_options, bundle) {
|
||||
const outputs = Object.values(bundle);
|
||||
const importedIds = /* @__PURE__ */ new Set();
|
||||
for (const output of outputs) {
|
||||
if (output.type === "chunk") {
|
||||
for (const id of output.imports) {
|
||||
importedIds.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const output of outputs) {
|
||||
if (output.type === "chunk" && output.facadeModuleId && internals.discoveredScripts.has(output.facadeModuleId) && !importedIds.has(output.fileName) && output.imports.length === 0 && output.dynamicImports.length === 0 && shouldInlineAsset(output.code, output.fileName, assetInlineLimit)) {
|
||||
internals.inlinedScripts.set(output.facadeModuleId, output.code.trim());
|
||||
delete bundle[output.fileName];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginScripts(internals) {
|
||||
return {
|
||||
targets: ["client"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
return {
|
||||
vitePlugin: vitePluginScripts(internals)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
pluginScripts,
|
||||
vitePluginScripts
|
||||
};
|
9
node_modules/astro/dist/core/build/plugins/plugin-ssr.d.ts
generated
vendored
Normal file
9
node_modules/astro/dist/core/build/plugins/plugin-ssr.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
export declare const SSR_VIRTUAL_MODULE_ID = "@astrojs-ssr-virtual-entry";
|
||||
export declare const RESOLVED_SSR_VIRTUAL_MODULE_ID: string;
|
||||
export declare function pluginSSR(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
||||
export declare const SPLIT_MODULE_ID = "@astro-page-split:";
|
||||
export declare const RESOLVED_SPLIT_MODULE_ID = "\0@astro-page-split:";
|
||||
export declare function pluginSSRSplit(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
281
node_modules/astro/dist/core/build/plugins/plugin-ssr.js
generated
vendored
Normal file
281
node_modules/astro/dist/core/build/plugins/plugin-ssr.js
generated
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { isFunctionPerRouteEnabled } from "../../../integrations/hooks.js";
|
||||
import { routeIsRedirect } from "../../redirects/index.js";
|
||||
import { VIRTUAL_ISLAND_MAP_ID } from "../../server-islands/vite-plugin-server-islands.js";
|
||||
import { isServerLikeOutput } from "../../util.js";
|
||||
import { addRollupInput } from "../add-rollup-input.js";
|
||||
import { SSR_MANIFEST_VIRTUAL_MODULE_ID } from "./plugin-manifest.js";
|
||||
import { MIDDLEWARE_MODULE_ID } from "./plugin-middleware.js";
|
||||
import { ASTRO_PAGE_MODULE_ID } from "./plugin-pages.js";
|
||||
import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
|
||||
import { getComponentFromVirtualModulePageName, getVirtualModulePageName } from "./util.js";
|
||||
const SSR_VIRTUAL_MODULE_ID = "@astrojs-ssr-virtual-entry";
|
||||
const RESOLVED_SSR_VIRTUAL_MODULE_ID = "\0" + SSR_VIRTUAL_MODULE_ID;
|
||||
const ADAPTER_VIRTUAL_MODULE_ID = "@astrojs-ssr-adapter";
|
||||
const RESOLVED_ADAPTER_VIRTUAL_MODULE_ID = "\0" + ADAPTER_VIRTUAL_MODULE_ID;
|
||||
function vitePluginAdapter(adapter) {
|
||||
return {
|
||||
name: "@astrojs/vite-plugin-astro-adapter",
|
||||
enforce: "post",
|
||||
resolveId(id) {
|
||||
if (id === ADAPTER_VIRTUAL_MODULE_ID) {
|
||||
return RESOLVED_ADAPTER_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === RESOLVED_ADAPTER_VIRTUAL_MODULE_ID) {
|
||||
return `export * from '${adapter.serverEntrypoint}';`;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function vitePluginSSR(internals, adapter, options) {
|
||||
return {
|
||||
name: "@astrojs/vite-plugin-astro-ssr-server",
|
||||
enforce: "post",
|
||||
options(opts) {
|
||||
const inputs = /* @__PURE__ */ new Set();
|
||||
for (const pageData of Object.values(options.allPages)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
inputs.add(getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component));
|
||||
}
|
||||
const adapterServerEntrypoint = options.settings.adapter?.serverEntrypoint;
|
||||
if (adapterServerEntrypoint) {
|
||||
inputs.add(ADAPTER_VIRTUAL_MODULE_ID);
|
||||
}
|
||||
inputs.add(SSR_VIRTUAL_MODULE_ID);
|
||||
return addRollupInput(opts, Array.from(inputs));
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id === SSR_VIRTUAL_MODULE_ID) {
|
||||
return RESOLVED_SSR_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === RESOLVED_SSR_VIRTUAL_MODULE_ID) {
|
||||
const { allPages } = options;
|
||||
const imports = [];
|
||||
const contents = [];
|
||||
const exports = [];
|
||||
let i = 0;
|
||||
const pageMap = [];
|
||||
for (const pageData of Object.values(allPages)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
const virtualModuleName = getVirtualModulePageName(
|
||||
ASTRO_PAGE_MODULE_ID,
|
||||
pageData.component
|
||||
);
|
||||
let module = await this.resolve(virtualModuleName);
|
||||
if (module) {
|
||||
const variable = `_page${i}`;
|
||||
imports.push(`const ${variable} = () => import("${virtualModuleName}");`);
|
||||
const pageData2 = internals.pagesByKeys.get(pageData.key);
|
||||
if (pageData2) {
|
||||
pageMap.push(`[${JSON.stringify(pageData2.component)}, ${variable}]`);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
contents.push(`const pageMap = new Map([
|
||||
${pageMap.join(",\n ")}
|
||||
]);`);
|
||||
exports.push(`export { pageMap }`);
|
||||
const middleware = await this.resolve(MIDDLEWARE_MODULE_ID);
|
||||
const ssrCode = generateSSRCode(options.settings, adapter, middleware.id);
|
||||
imports.push(...ssrCode.imports);
|
||||
contents.push(...ssrCode.contents);
|
||||
return [...imports, ...contents, ...exports].join("\n");
|
||||
}
|
||||
},
|
||||
async generateBundle(_opts, bundle) {
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "asset") {
|
||||
internals.staticFiles.add(chunk.fileName);
|
||||
}
|
||||
}
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "asset") {
|
||||
continue;
|
||||
}
|
||||
if (chunk.modules[RESOLVED_SSR_VIRTUAL_MODULE_ID]) {
|
||||
internals.ssrEntryChunk = chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginSSR(options, internals) {
|
||||
const ssr = isServerLikeOutput(options.settings.config);
|
||||
const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
const adapter = options.settings.adapter;
|
||||
let ssrPlugin = ssr && functionPerRouteEnabled === false ? vitePluginSSR(internals, adapter, options) : void 0;
|
||||
const vitePlugin = [vitePluginAdapter(adapter)];
|
||||
if (ssrPlugin) {
|
||||
vitePlugin.unshift(ssrPlugin);
|
||||
}
|
||||
return {
|
||||
enforce: "after-user-plugins",
|
||||
vitePlugin
|
||||
};
|
||||
},
|
||||
"build:post": async () => {
|
||||
if (!ssr) {
|
||||
return;
|
||||
}
|
||||
if (functionPerRouteEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!internals.ssrEntryChunk) {
|
||||
throw new Error(`Did not generate an entry chunk for SSR`);
|
||||
}
|
||||
internals.ssrEntryChunk.fileName = options.settings.config.build.serverEntry;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const SPLIT_MODULE_ID = "@astro-page-split:";
|
||||
const RESOLVED_SPLIT_MODULE_ID = "\0@astro-page-split:";
|
||||
function vitePluginSSRSplit(internals, adapter, options) {
|
||||
return {
|
||||
name: "@astrojs/vite-plugin-astro-ssr-split",
|
||||
enforce: "post",
|
||||
options(opts) {
|
||||
const inputs = /* @__PURE__ */ new Set();
|
||||
for (const pageData of Object.values(options.allPages)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
inputs.add(getVirtualModulePageName(SPLIT_MODULE_ID, pageData.component));
|
||||
}
|
||||
return addRollupInput(opts, Array.from(inputs));
|
||||
},
|
||||
resolveId(id) {
|
||||
if (id.startsWith(SPLIT_MODULE_ID)) {
|
||||
return "\0" + id;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
|
||||
const imports = [];
|
||||
const contents = [];
|
||||
const exports = [];
|
||||
const componentPath = getComponentFromVirtualModulePageName(RESOLVED_SPLIT_MODULE_ID, id);
|
||||
const virtualModuleName = getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, componentPath);
|
||||
let module = await this.resolve(virtualModuleName);
|
||||
if (module) {
|
||||
imports.push(`import * as pageModule from "${virtualModuleName}";`);
|
||||
}
|
||||
const middleware = await this.resolve(MIDDLEWARE_MODULE_ID);
|
||||
const ssrCode = generateSSRCode(options.settings, adapter, middleware.id);
|
||||
imports.push(...ssrCode.imports);
|
||||
contents.push(...ssrCode.contents);
|
||||
exports.push("export { pageModule }");
|
||||
return [...imports, ...contents, ...exports].join("\n");
|
||||
}
|
||||
},
|
||||
async generateBundle(_opts, bundle) {
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "asset") {
|
||||
internals.staticFiles.add(chunk.fileName);
|
||||
}
|
||||
}
|
||||
for (const [, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type === "asset") {
|
||||
continue;
|
||||
}
|
||||
for (const moduleKey of Object.keys(chunk.modules)) {
|
||||
if (moduleKey.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
|
||||
storeEntryPoint(moduleKey, options, internals, chunk.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function pluginSSRSplit(options, internals) {
|
||||
const ssr = isServerLikeOutput(options.settings.config);
|
||||
const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
|
||||
return {
|
||||
targets: ["server"],
|
||||
hooks: {
|
||||
"build:before": () => {
|
||||
const adapter = options.settings.adapter;
|
||||
let ssrPlugin = ssr && functionPerRouteEnabled ? vitePluginSSRSplit(internals, adapter, options) : void 0;
|
||||
const vitePlugin = [vitePluginAdapter(adapter)];
|
||||
if (ssrPlugin) {
|
||||
vitePlugin.unshift(ssrPlugin);
|
||||
}
|
||||
return {
|
||||
enforce: "after-user-plugins",
|
||||
vitePlugin
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function generateSSRCode(settings, adapter, middlewareId) {
|
||||
const edgeMiddleware = adapter?.adapterFeatures?.edgeMiddleware ?? false;
|
||||
const pageMap = isFunctionPerRouteEnabled(adapter) ? "pageModule" : "pageMap";
|
||||
const imports = [
|
||||
`import { renderers } from '${RENDERERS_MODULE_ID}';`,
|
||||
`import * as serverEntrypointModule from '${ADAPTER_VIRTUAL_MODULE_ID}';`,
|
||||
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
|
||||
settings.config.experimental.serverIslands ? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';` : ""
|
||||
];
|
||||
const contents = [
|
||||
settings.config.experimental.serverIslands ? "" : `const serverIslandMap = new Map()`,
|
||||
`const _manifest = Object.assign(defaultManifest, {`,
|
||||
` ${pageMap},`,
|
||||
` serverIslandMap,`,
|
||||
` renderers,`,
|
||||
` middleware: ${edgeMiddleware ? "undefined" : `() => import("${middlewareId}")`}`,
|
||||
`});`,
|
||||
`const _args = ${adapter.args ? JSON.stringify(adapter.args, null, 4) : "undefined"};`,
|
||||
adapter.exports ? `const _exports = serverEntrypointModule.createExports(_manifest, _args);` : "",
|
||||
...adapter.exports?.map((name) => {
|
||||
if (name === "default") {
|
||||
return `export default _exports.default;`;
|
||||
} else {
|
||||
return `export const ${name} = _exports['${name}'];`;
|
||||
}
|
||||
}) ?? [],
|
||||
// NOTE: This is intentionally obfuscated!
|
||||
// Do NOT simplify this to something like `serverEntrypointModule.start?.(_manifest, _args)`
|
||||
// They are NOT equivalent! Some bundlers will throw if `start` is not exported, but we
|
||||
// only want to silently ignore it... hence the dynamic, obfuscated weirdness.
|
||||
`const _start = 'start';
|
||||
if (_start in serverEntrypointModule) {
|
||||
serverEntrypointModule[_start](_manifest, _args);
|
||||
}`
|
||||
];
|
||||
return {
|
||||
imports,
|
||||
contents
|
||||
};
|
||||
}
|
||||
function storeEntryPoint(moduleKey, options, internals, fileName) {
|
||||
const componentPath = getComponentFromVirtualModulePageName(RESOLVED_SPLIT_MODULE_ID, moduleKey);
|
||||
for (const pageData of Object.values(options.allPages)) {
|
||||
if (componentPath == pageData.component) {
|
||||
const publicPath = fileURLToPath(options.settings.config.build.server);
|
||||
internals.entryPoints.set(pageData.route, pathToFileURL(join(publicPath, fileName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
RESOLVED_SPLIT_MODULE_ID,
|
||||
RESOLVED_SSR_VIRTUAL_MODULE_ID,
|
||||
SPLIT_MODULE_ID,
|
||||
SSR_VIRTUAL_MODULE_ID,
|
||||
pluginSSR,
|
||||
pluginSSRSplit
|
||||
};
|
42
node_modules/astro/dist/core/build/plugins/util.d.ts
generated
vendored
Normal file
42
node_modules/astro/dist/core/build/plugins/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { BuildOptions, Rollup, Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../internal.js';
|
||||
import type { PageBuildData } from '../types.js';
|
||||
type OutputOptionsHook = Extract<VitePlugin['outputOptions'], Function>;
|
||||
type OutputOptions = Parameters<OutputOptionsHook>[0];
|
||||
type ExtendManualChunksHooks = {
|
||||
before?: Rollup.GetManualChunk;
|
||||
after?: Rollup.GetManualChunk;
|
||||
};
|
||||
export declare function extendManualChunks(outputOptions: OutputOptions, hooks: ExtendManualChunksHooks): void;
|
||||
export declare const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
|
||||
export declare const ASTRO_PAGE_KEY_SEPARATOR = "&";
|
||||
/**
|
||||
* Generate a unique key to identify each page in the build process.
|
||||
* @param route Usually pageData.route.route
|
||||
* @param componentPath Usually pageData.component
|
||||
*/
|
||||
export declare function makePageDataKey(route: string, componentPath: string): string;
|
||||
/**
|
||||
* Prevents Rollup from triggering other plugins in the process by masking the extension (hence the virtual file).
|
||||
* Inverse function of getComponentFromVirtualModulePageName() below.
|
||||
* @param virtualModulePrefix The prefix used to create the virtual module
|
||||
* @param path Page component path
|
||||
*/
|
||||
export declare function getVirtualModulePageName(virtualModulePrefix: string, path: string): string;
|
||||
/**
|
||||
* From the VirtualModulePageName, and the internals, get all pageDatas that use this
|
||||
* component as their entry point.
|
||||
* @param virtualModulePrefix The prefix used to create the virtual module
|
||||
* @param id Virtual module name
|
||||
*/
|
||||
export declare function getPagesFromVirtualModulePageName(internals: BuildInternals, virtualModulePrefix: string, id: string): PageBuildData[];
|
||||
/**
|
||||
* From the VirtualModulePageName, get the component path.
|
||||
* Remember that the component can be use by multiple routes.
|
||||
* Inverse function of getVirtualModulePageName() above.
|
||||
* @param virtualModulePrefix The prefix at the beginning of the virtual module
|
||||
* @param id Virtual module name
|
||||
*/
|
||||
export declare function getComponentFromVirtualModulePageName(virtualModulePrefix: string, id: string): string;
|
||||
export declare function shouldInlineAsset(assetContent: string, assetPath: string, assetsInlineLimit: NonNullable<BuildOptions['assetsInlineLimit']>): boolean;
|
||||
export {};
|
70
node_modules/astro/dist/core/build/plugins/util.js
generated
vendored
Normal file
70
node_modules/astro/dist/core/build/plugins/util.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import { extname } from "node:path";
|
||||
function extendManualChunks(outputOptions, hooks) {
|
||||
const manualChunks = outputOptions.manualChunks;
|
||||
outputOptions.manualChunks = function(id, meta) {
|
||||
if (hooks.before) {
|
||||
let value = hooks.before(id, meta);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
if (typeof manualChunks == "object") {
|
||||
if (id in manualChunks) {
|
||||
let value = manualChunks[id];
|
||||
return value[0];
|
||||
}
|
||||
} else if (typeof manualChunks === "function") {
|
||||
const outid = manualChunks.call(this, id, meta);
|
||||
if (outid) {
|
||||
return outid;
|
||||
}
|
||||
}
|
||||
if (hooks.after) {
|
||||
return hooks.after(id, meta) || null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
|
||||
const ASTRO_PAGE_KEY_SEPARATOR = "&";
|
||||
function makePageDataKey(route, componentPath) {
|
||||
return route + ASTRO_PAGE_KEY_SEPARATOR + componentPath;
|
||||
}
|
||||
function getVirtualModulePageName(virtualModulePrefix, path) {
|
||||
const extension = extname(path);
|
||||
return virtualModulePrefix + (extension.startsWith(".") ? path.slice(0, -extension.length) + extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN) : path);
|
||||
}
|
||||
function getPagesFromVirtualModulePageName(internals, virtualModulePrefix, id) {
|
||||
const path = getComponentFromVirtualModulePageName(virtualModulePrefix, id);
|
||||
const pages = [];
|
||||
internals.pagesByKeys.forEach((pageData) => {
|
||||
if (pageData.component === path) {
|
||||
pages.push(pageData);
|
||||
}
|
||||
});
|
||||
return pages;
|
||||
}
|
||||
function getComponentFromVirtualModulePageName(virtualModulePrefix, id) {
|
||||
return id.slice(virtualModulePrefix.length).replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
|
||||
}
|
||||
function shouldInlineAsset(assetContent, assetPath, assetsInlineLimit) {
|
||||
if (typeof assetsInlineLimit === "function") {
|
||||
const result = assetsInlineLimit(assetPath, Buffer.from(assetContent));
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
return Buffer.byteLength(assetContent) < 4096;
|
||||
}
|
||||
}
|
||||
return Buffer.byteLength(assetContent) < Number(assetsInlineLimit);
|
||||
}
|
||||
export {
|
||||
ASTRO_PAGE_EXTENSION_POST_PATTERN,
|
||||
ASTRO_PAGE_KEY_SEPARATOR,
|
||||
extendManualChunks,
|
||||
getComponentFromVirtualModulePageName,
|
||||
getPagesFromVirtualModulePageName,
|
||||
getVirtualModulePageName,
|
||||
makePageDataKey,
|
||||
shouldInlineAsset
|
||||
};
|
41
node_modules/astro/dist/core/build/static-build.d.ts
generated
vendored
Normal file
41
node_modules/astro/dist/core/build/static-build.d.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import type { RouteData } from '../../@types/astro.js';
|
||||
import { type BuildInternals } from '../../core/build/internal.js';
|
||||
import type { StaticBuildOptions } from './types.js';
|
||||
export declare function viteBuild(opts: StaticBuildOptions): Promise<{
|
||||
internals: BuildInternals;
|
||||
ssrOutputChunkNames: string[];
|
||||
}>;
|
||||
export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[]): Promise<void>;
|
||||
export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void[] | undefined>;
|
||||
/**
|
||||
* This function takes the virtual module name of any page entrypoint and
|
||||
* transforms it to generate a final `.mjs` output file.
|
||||
*
|
||||
* Input: `@astro-page:src/pages/index@_@astro`
|
||||
* Output: `pages/index.astro.mjs`
|
||||
* Input: `@astro-page:../node_modules/my-dep/injected@_@astro`
|
||||
* Output: `pages/injected.mjs`
|
||||
*
|
||||
* 1. We clean the `facadeModuleId` by removing the `ASTRO_PAGE_MODULE_ID` prefix and `ASTRO_PAGE_EXTENSION_POST_PATTERN`.
|
||||
* 2. We find the matching route pattern in the manifest (or fallback to the cleaned module id)
|
||||
* 3. We replace square brackets with underscore (`[slug]` => `_slug_`) and `...` with `` (`[...slug]` => `_---slug_`).
|
||||
* 4. We append the `.mjs` extension, so the file will always be an ESM module
|
||||
*
|
||||
* @param prefix string
|
||||
* @param facadeModuleId string
|
||||
* @param pages AllPagesData
|
||||
*/
|
||||
export declare function makeAstroPageEntryPointFileName(prefix: string, facadeModuleId: string, routes: RouteData[]): string;
|
||||
/**
|
||||
* The `facadeModuleId` has a shape like: \0@astro-serverless-page:src/pages/index@_@astro.
|
||||
*
|
||||
* 1. We call `makeAstroPageEntryPointFileName` which normalise its name, making it like a file path
|
||||
* 2. We split the file path using the file system separator and attempt to retrieve the last entry
|
||||
* 3. The last entry should be the file
|
||||
* 4. We prepend the file name with `entry.`
|
||||
* 5. We built the file path again, using the new en3built in the previous step
|
||||
*
|
||||
* @param facadeModuleId
|
||||
* @param opts
|
||||
*/
|
||||
export declare function makeSplitEntryPointFileName(facadeModuleId: string, routes: RouteData[]): string;
|
406
node_modules/astro/dist/core/build/static-build.js
generated
vendored
Normal file
406
node_modules/astro/dist/core/build/static-build.js
generated
vendored
Normal file
@@ -0,0 +1,406 @@
|
||||
import fs from "node:fs";
|
||||
import path, { extname } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { teardown } from "@astrojs/compiler";
|
||||
import glob from "fast-glob";
|
||||
import { bgGreen, bgMagenta, black, green } from "kleur/colors";
|
||||
import * as vite from "vite";
|
||||
import { PROPAGATED_ASSET_FLAG } from "../../content/consts.js";
|
||||
import {
|
||||
getSymlinkedContentCollections,
|
||||
hasAnyContentFlag,
|
||||
reverseSymlink
|
||||
} from "../../content/utils.js";
|
||||
import {
|
||||
createBuildInternals,
|
||||
getPageDatasWithPublicKey
|
||||
} from "../../core/build/internal.js";
|
||||
import { emptyDir, removeEmptyDirs } from "../../core/fs/index.js";
|
||||
import { appendForwardSlash, prependForwardSlash, removeFileExtension } from "../../core/path.js";
|
||||
import { isModeServerWithNoAdapter, isServerLikeOutput } from "../../core/util.js";
|
||||
import { runHookBuildSetup } from "../../integrations/hooks.js";
|
||||
import { getOutputDirectory } from "../../prerender/utils.js";
|
||||
import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
||||
import { AstroError, AstroErrorData } from "../errors/index.js";
|
||||
import { routeIsRedirect } from "../redirects/index.js";
|
||||
import { getOutDirWithinCwd } from "./common.js";
|
||||
import { CHUNKS_PATH } from "./consts.js";
|
||||
import { generatePages } from "./generate.js";
|
||||
import { trackPageData } from "./internal.js";
|
||||
import { createPluginContainer } from "./plugin.js";
|
||||
import { registerAllPlugins } from "./plugins/index.js";
|
||||
import { copyContentToCache } from "./plugins/plugin-content.js";
|
||||
import { RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID } from "./plugins/plugin-manifest.js";
|
||||
import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
|
||||
import { RESOLVED_RENDERERS_MODULE_ID } from "./plugins/plugin-renderers.js";
|
||||
import { RESOLVED_SPLIT_MODULE_ID, RESOLVED_SSR_VIRTUAL_MODULE_ID } from "./plugins/plugin-ssr.js";
|
||||
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
|
||||
import { encodeName, getTimeStat, viteBuildReturnToRollupOutputs } from "./util.js";
|
||||
async function viteBuild(opts) {
|
||||
const { allPages, settings, logger } = opts;
|
||||
if (isModeServerWithNoAdapter(opts.settings)) {
|
||||
throw new AstroError(AstroErrorData.NoAdapterInstalled);
|
||||
}
|
||||
settings.timer.start("SSR build");
|
||||
const pageInput = /* @__PURE__ */ new Set();
|
||||
const internals = createBuildInternals();
|
||||
for (const pageData of Object.values(allPages)) {
|
||||
const astroModuleURL = new URL("./" + pageData.component, settings.config.root);
|
||||
const astroModuleId = prependForwardSlash(pageData.component);
|
||||
trackPageData(internals, pageData.component, pageData, astroModuleId, astroModuleURL);
|
||||
if (!routeIsRedirect(pageData.route)) {
|
||||
pageInput.add(astroModuleId);
|
||||
}
|
||||
}
|
||||
if (settings.config?.vite?.build?.emptyOutDir !== false) {
|
||||
emptyDir(settings.config.outDir, new Set(".git"));
|
||||
}
|
||||
const container = createPluginContainer(opts, internals);
|
||||
registerAllPlugins(container);
|
||||
const ssrTime = performance.now();
|
||||
opts.logger.info("build", `Building ${settings.config.output} entrypoints...`);
|
||||
const ssrOutput = await ssrBuild(opts, internals, pageInput, container, logger);
|
||||
opts.logger.info("build", green(`\u2713 Completed in ${getTimeStat(ssrTime, performance.now())}.`));
|
||||
settings.timer.end("SSR build");
|
||||
settings.timer.start("Client build");
|
||||
const rendererClientEntrypoints = settings.renderers.map((r) => r.clientEntrypoint).filter((a) => typeof a === "string");
|
||||
const clientInput = /* @__PURE__ */ new Set([
|
||||
...internals.cachedClientEntries,
|
||||
...internals.discoveredHydratedComponents.keys(),
|
||||
...internals.discoveredClientOnlyComponents.keys(),
|
||||
...rendererClientEntrypoints,
|
||||
...internals.discoveredScripts
|
||||
]);
|
||||
if (settings.scripts.some((script) => script.stage === "page")) {
|
||||
clientInput.add(PAGE_SCRIPT_ID);
|
||||
}
|
||||
const clientOutput = await clientBuild(opts, internals, clientInput, container);
|
||||
const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput);
|
||||
const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []);
|
||||
await runPostBuildHooks(container, ssrOutputs, clientOutputs);
|
||||
settings.timer.end("Client build");
|
||||
internals.ssrEntryChunk = void 0;
|
||||
if (opts.teardownCompiler) {
|
||||
teardown();
|
||||
}
|
||||
const ssrOutputChunkNames = [];
|
||||
for (const output of ssrOutputs) {
|
||||
for (const chunk of output.output) {
|
||||
if (chunk.type === "chunk") {
|
||||
ssrOutputChunkNames.push(chunk.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return { internals, ssrOutputChunkNames };
|
||||
}
|
||||
async function staticBuild(opts, internals, ssrOutputChunkNames) {
|
||||
const { settings } = opts;
|
||||
if (settings.config.output === "static") {
|
||||
settings.timer.start("Static generate");
|
||||
await generatePages(opts, internals);
|
||||
await cleanServerOutput(opts, ssrOutputChunkNames, internals);
|
||||
settings.timer.end("Static generate");
|
||||
} else if (isServerLikeOutput(settings.config)) {
|
||||
settings.timer.start("Server generate");
|
||||
await generatePages(opts, internals);
|
||||
await cleanStaticOutput(opts, internals);
|
||||
await ssrMoveAssets(opts);
|
||||
settings.timer.end("Server generate");
|
||||
}
|
||||
}
|
||||
async function ssrBuild(opts, internals, input, container, logger) {
|
||||
const buildID = Date.now().toString();
|
||||
const { allPages, settings, viteConfig } = opts;
|
||||
const ssr = isServerLikeOutput(settings.config);
|
||||
const out = getOutputDirectory(settings.config);
|
||||
const routes = Object.values(allPages).flatMap((pageData) => pageData.route);
|
||||
const isContentCache = !ssr && settings.config.experimental.contentCollectionCache;
|
||||
const { lastVitePlugins, vitePlugins } = await container.runBeforeHook("server", input);
|
||||
const contentDir = new URL("./src/content", settings.config.root);
|
||||
const symlinks = await getSymlinkedContentCollections({ contentDir, logger, fs });
|
||||
const viteBuildConfig = {
|
||||
...viteConfig,
|
||||
mode: viteConfig.mode || "production",
|
||||
logLevel: viteConfig.logLevel ?? "error",
|
||||
build: {
|
||||
target: "esnext",
|
||||
// Vite defaults cssMinify to false in SSR by default, but we want to minify it
|
||||
// as the CSS generated are used and served to the client.
|
||||
cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
|
||||
...viteConfig.build,
|
||||
emptyOutDir: false,
|
||||
manifest: false,
|
||||
outDir: fileURLToPath(out),
|
||||
copyPublicDir: !ssr,
|
||||
rollupOptions: {
|
||||
...viteConfig.build?.rollupOptions,
|
||||
// Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
|
||||
preserveEntrySignatures: "exports-only",
|
||||
input: [],
|
||||
output: {
|
||||
hoistTransitiveImports: isContentCache,
|
||||
format: "esm",
|
||||
minifyInternalExports: !isContentCache,
|
||||
// Server chunks can't go in the assets (_astro) folder
|
||||
// We need to keep these separate
|
||||
chunkFileNames(chunkInfo) {
|
||||
const { name } = chunkInfo;
|
||||
let prefix = CHUNKS_PATH;
|
||||
let suffix = "_[hash].mjs";
|
||||
if (isContentCache) {
|
||||
prefix += `${buildID}/`;
|
||||
suffix = ".mjs";
|
||||
if (name.includes("/content/")) {
|
||||
const parts = name.split("/");
|
||||
if (parts.at(1) === "content") {
|
||||
return encodeName(parts.slice(1).join("/"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
||||
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
||||
return [prefix, sanitizedName, suffix].join("");
|
||||
}
|
||||
if (name.startsWith("pages/")) {
|
||||
const sanitizedName = name.split(".")[0];
|
||||
return [prefix, sanitizedName, suffix].join("");
|
||||
}
|
||||
const encoded = encodeName(name);
|
||||
return [prefix, encoded, suffix].join("");
|
||||
},
|
||||
assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
|
||||
...viteConfig.build?.rollupOptions?.output,
|
||||
entryFileNames(chunkInfo) {
|
||||
if (chunkInfo.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
|
||||
return makeAstroPageEntryPointFileName(
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
chunkInfo.facadeModuleId,
|
||||
routes
|
||||
);
|
||||
} else if (chunkInfo.facadeModuleId?.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
|
||||
return makeSplitEntryPointFileName(chunkInfo.facadeModuleId, routes);
|
||||
} else if (chunkInfo.facadeModuleId === RESOLVED_SSR_VIRTUAL_MODULE_ID) {
|
||||
return opts.settings.config.build.serverEntry;
|
||||
} else if (chunkInfo.facadeModuleId === RESOLVED_RENDERERS_MODULE_ID) {
|
||||
return "renderers.mjs";
|
||||
} else if (chunkInfo.facadeModuleId === RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID) {
|
||||
return "manifest_[hash].mjs";
|
||||
} else if (chunkInfo.facadeModuleId === settings.adapter?.serverEntrypoint) {
|
||||
return "adapter_[hash].mjs";
|
||||
} else if (settings.config.experimental.contentCollectionCache && chunkInfo.facadeModuleId && hasAnyContentFlag(chunkInfo.facadeModuleId)) {
|
||||
const moduleId = reverseSymlink({
|
||||
symlinks,
|
||||
entry: chunkInfo.facadeModuleId,
|
||||
contentDir
|
||||
});
|
||||
const [srcRelative, flag] = moduleId.split("/src/")[1].split("?");
|
||||
if (flag === PROPAGATED_ASSET_FLAG) {
|
||||
return encodeName(`${removeFileExtension(srcRelative)}.entry.mjs`);
|
||||
}
|
||||
return encodeName(`${removeFileExtension(srcRelative)}.mjs`);
|
||||
} else {
|
||||
return "[name].mjs";
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ssr: true,
|
||||
ssrEmitAssets: true,
|
||||
// improve build performance
|
||||
minify: false,
|
||||
modulePreload: { polyfill: false },
|
||||
reportCompressedSize: false
|
||||
},
|
||||
plugins: [...vitePlugins, ...viteConfig.plugins || [], ...lastVitePlugins],
|
||||
envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
|
||||
base: settings.config.base
|
||||
};
|
||||
const updatedViteBuildConfig = await runHookBuildSetup({
|
||||
config: settings.config,
|
||||
pages: getPageDatasWithPublicKey(internals.pagesByKeys),
|
||||
vite: viteBuildConfig,
|
||||
target: "server",
|
||||
logger: opts.logger
|
||||
});
|
||||
return await vite.build(updatedViteBuildConfig);
|
||||
}
|
||||
async function clientBuild(opts, internals, input, container) {
|
||||
const { settings, viteConfig } = opts;
|
||||
const ssr = isServerLikeOutput(settings.config);
|
||||
const out = ssr ? settings.config.build.client : getOutDirWithinCwd(settings.config.outDir);
|
||||
if (!input.size) {
|
||||
if (ssr) {
|
||||
await copyFiles(settings.config.publicDir, out, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const { lastVitePlugins, vitePlugins } = await container.runBeforeHook("client", input);
|
||||
opts.logger.info("SKIP_FORMAT", `
|
||||
${bgGreen(black(" building client (vite) "))}`);
|
||||
const viteBuildConfig = {
|
||||
...viteConfig,
|
||||
mode: viteConfig.mode || "production",
|
||||
build: {
|
||||
target: "esnext",
|
||||
...viteConfig.build,
|
||||
emptyOutDir: false,
|
||||
outDir: fileURLToPath(out),
|
||||
copyPublicDir: ssr,
|
||||
rollupOptions: {
|
||||
...viteConfig.build?.rollupOptions,
|
||||
input: Array.from(input),
|
||||
output: {
|
||||
format: "esm",
|
||||
entryFileNames: `${settings.config.build.assets}/[name].[hash].js`,
|
||||
chunkFileNames: `${settings.config.build.assets}/[name].[hash].js`,
|
||||
assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
|
||||
...viteConfig.build?.rollupOptions?.output
|
||||
},
|
||||
preserveEntrySignatures: "exports-only"
|
||||
}
|
||||
},
|
||||
plugins: [...vitePlugins, ...viteConfig.plugins || [], ...lastVitePlugins],
|
||||
envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
|
||||
base: settings.config.base
|
||||
};
|
||||
await runHookBuildSetup({
|
||||
config: settings.config,
|
||||
pages: getPageDatasWithPublicKey(internals.pagesByKeys),
|
||||
vite: viteBuildConfig,
|
||||
target: "client",
|
||||
logger: opts.logger
|
||||
});
|
||||
const buildResult = await vite.build(viteBuildConfig);
|
||||
return buildResult;
|
||||
}
|
||||
async function runPostBuildHooks(container, ssrOutputs, clientOutputs) {
|
||||
const mutations = await container.runPostHook(ssrOutputs, clientOutputs);
|
||||
const config = container.options.settings.config;
|
||||
const build = container.options.settings.config.build;
|
||||
for (const [fileName, mutation] of mutations) {
|
||||
const root = isServerLikeOutput(config) ? mutation.targets.includes("server") ? build.server : build.client : getOutDirWithinCwd(config.outDir);
|
||||
const fullPath = path.join(fileURLToPath(root), fileName);
|
||||
const fileURL = pathToFileURL(fullPath);
|
||||
await fs.promises.mkdir(new URL("./", fileURL), { recursive: true });
|
||||
await fs.promises.writeFile(fileURL, mutation.code, "utf-8");
|
||||
}
|
||||
}
|
||||
async function cleanStaticOutput(opts, internals) {
|
||||
const ssr = isServerLikeOutput(opts.settings.config);
|
||||
const out = ssr ? opts.settings.config.build.server : getOutDirWithinCwd(opts.settings.config.outDir);
|
||||
await Promise.all(
|
||||
internals.prerenderOnlyChunks.map(async (chunk) => {
|
||||
const url = new URL(chunk.fileName, out);
|
||||
try {
|
||||
if (chunk.isEntry || chunk.isDynamicEntry) {
|
||||
await fs.promises.writeFile(
|
||||
url,
|
||||
"// Contents removed by Astro as it's used for prerendering only",
|
||||
"utf-8"
|
||||
);
|
||||
} else {
|
||||
await fs.promises.unlink(url);
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
async function cleanServerOutput(opts, ssrOutputChunkNames, internals) {
|
||||
const out = getOutDirWithinCwd(opts.settings.config.outDir);
|
||||
const files = ssrOutputChunkNames.filter((f) => f.endsWith(".mjs"));
|
||||
if (internals.manifestFileName) {
|
||||
files.push(internals.manifestFileName);
|
||||
}
|
||||
if (files.length) {
|
||||
await Promise.all(
|
||||
files.map(async (filename) => {
|
||||
const url = new URL(filename, out);
|
||||
const map = new URL(url + ".map");
|
||||
await Promise.all([fs.promises.rm(url), fs.promises.rm(new URL(map)).catch(() => {
|
||||
})]);
|
||||
})
|
||||
);
|
||||
removeEmptyDirs(out);
|
||||
}
|
||||
if (out.toString() !== opts.settings.config.outDir.toString()) {
|
||||
const fileNames = await fs.promises.readdir(out);
|
||||
await Promise.all(
|
||||
fileNames.filter((fileName) => fileName.endsWith(".d.ts")).map((fileName) => fs.promises.rm(new URL(fileName, out)))
|
||||
);
|
||||
await copyFiles(out, opts.settings.config.outDir, true);
|
||||
await fs.promises.rm(out, { recursive: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
async function copyFiles(fromFolder, toFolder, includeDotfiles = false) {
|
||||
const files = await glob("**/*", {
|
||||
cwd: fileURLToPath(fromFolder),
|
||||
dot: includeDotfiles
|
||||
});
|
||||
if (files.length === 0) return;
|
||||
return await Promise.all(
|
||||
files.map(async function copyFile(filename) {
|
||||
const from = new URL(filename, fromFolder);
|
||||
const to = new URL(filename, toFolder);
|
||||
const lastFolder = new URL("./", to);
|
||||
return fs.promises.mkdir(lastFolder, { recursive: true }).then(async function fsCopyFile() {
|
||||
const p = await fs.promises.copyFile(from, to, fs.constants.COPYFILE_FICLONE);
|
||||
return p;
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
async function ssrMoveAssets(opts) {
|
||||
opts.logger.info("build", "Rearranging server assets...");
|
||||
const serverRoot = opts.settings.config.output === "static" ? opts.settings.config.build.client : opts.settings.config.build.server;
|
||||
const clientRoot = opts.settings.config.build.client;
|
||||
const assets = opts.settings.config.build.assets;
|
||||
const serverAssets = new URL(`./${assets}/`, appendForwardSlash(serverRoot.toString()));
|
||||
const clientAssets = new URL(`./${assets}/`, appendForwardSlash(clientRoot.toString()));
|
||||
const files = await glob(`**/*`, {
|
||||
cwd: fileURLToPath(serverAssets)
|
||||
});
|
||||
if (files.length > 0) {
|
||||
await Promise.all(
|
||||
files.map(async function moveAsset(filename) {
|
||||
const currentUrl = new URL(filename, appendForwardSlash(serverAssets.toString()));
|
||||
const clientUrl = new URL(filename, appendForwardSlash(clientAssets.toString()));
|
||||
const dir = new URL(path.parse(clientUrl.href).dir);
|
||||
if (!fs.existsSync(dir)) await fs.promises.mkdir(dir, { recursive: true });
|
||||
return fs.promises.rename(currentUrl, clientUrl);
|
||||
})
|
||||
);
|
||||
removeEmptyDirs(serverAssets);
|
||||
}
|
||||
}
|
||||
function makeAstroPageEntryPointFileName(prefix, facadeModuleId, routes) {
|
||||
const pageModuleId = facadeModuleId.replace(prefix, "").replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
|
||||
const route = routes.find((routeData) => routeData.component === pageModuleId);
|
||||
const name = route?.route ?? pageModuleId;
|
||||
return `pages${name.replace(/\/$/, "/index").replaceAll(/[[\]]/g, "_").replaceAll("...", "---")}.astro.mjs`;
|
||||
}
|
||||
function makeSplitEntryPointFileName(facadeModuleId, routes) {
|
||||
const filePath = `${makeAstroPageEntryPointFileName(
|
||||
RESOLVED_SPLIT_MODULE_ID,
|
||||
facadeModuleId,
|
||||
routes
|
||||
)}`;
|
||||
const pathComponents = filePath.split(path.sep);
|
||||
const lastPathComponent = pathComponents.pop();
|
||||
if (lastPathComponent) {
|
||||
const extension = extname(lastPathComponent);
|
||||
if (extension.length > 0) {
|
||||
const newFileName = `entry.${lastPathComponent}`;
|
||||
return [...pathComponents, newFileName].join(path.sep);
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
export {
|
||||
copyFiles,
|
||||
makeAstroPageEntryPointFileName,
|
||||
makeSplitEntryPointFileName,
|
||||
staticBuild,
|
||||
viteBuild
|
||||
};
|
54
node_modules/astro/dist/core/build/types.d.ts
generated
vendored
Normal file
54
node_modules/astro/dist/core/build/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import type * as vite from 'vite';
|
||||
import type { InlineConfig } from 'vite';
|
||||
import type { AstroSettings, ComponentInstance, ManifestData, MiddlewareHandler, RouteData, RuntimeMode, SSRLoadedRenderer } from '../../@types/astro.js';
|
||||
import type { Logger } from '../logger/core.js';
|
||||
export type ComponentPath = string;
|
||||
export type ViteID = string;
|
||||
export type StylesheetAsset = {
|
||||
type: 'inline';
|
||||
content: string;
|
||||
} | {
|
||||
type: 'external';
|
||||
src: string;
|
||||
};
|
||||
export type HoistedScriptAsset = {
|
||||
type: 'inline' | 'external';
|
||||
value: string;
|
||||
};
|
||||
export interface PageBuildData {
|
||||
key: string;
|
||||
component: ComponentPath;
|
||||
route: RouteData;
|
||||
moduleSpecifier: string;
|
||||
hoistedScript: HoistedScriptAsset | undefined;
|
||||
styles: Array<{
|
||||
depth: number;
|
||||
order: number;
|
||||
sheet: StylesheetAsset;
|
||||
}>;
|
||||
}
|
||||
export type AllPagesData = Record<ComponentPath, PageBuildData>;
|
||||
/** Options for the static build */
|
||||
export interface StaticBuildOptions {
|
||||
allPages: AllPagesData;
|
||||
settings: AstroSettings;
|
||||
logger: Logger;
|
||||
manifest: ManifestData;
|
||||
mode: RuntimeMode;
|
||||
origin: string;
|
||||
pageNames: string[];
|
||||
viteConfig: InlineConfig;
|
||||
teardownCompiler: boolean;
|
||||
key: Promise<CryptoKey>;
|
||||
}
|
||||
type ImportComponentInstance = () => Promise<ComponentInstance>;
|
||||
export interface SinglePageBuiltModule {
|
||||
page: ImportComponentInstance;
|
||||
/**
|
||||
* The `onRequest` hook exported by the middleware
|
||||
*/
|
||||
onRequest?: MiddlewareHandler;
|
||||
renderers: SSRLoadedRenderer[];
|
||||
}
|
||||
export type ViteBuildReturn = Awaited<ReturnType<typeof vite.build>>;
|
||||
export {};
|
0
node_modules/astro/dist/core/build/types.js
generated
vendored
Normal file
0
node_modules/astro/dist/core/build/types.js
generated
vendored
Normal file
11
node_modules/astro/dist/core/build/util.d.ts
generated
vendored
Normal file
11
node_modules/astro/dist/core/build/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { Rollup } from 'vite';
|
||||
import type { AstroConfig } from '../../@types/astro.js';
|
||||
import type { ViteBuildReturn } from './types.js';
|
||||
export declare function getTimeStat(timeStart: number, timeEnd: number): string;
|
||||
/**
|
||||
* Given the Astro configuration, it tells if a slash should be appended or not
|
||||
*/
|
||||
export declare function shouldAppendForwardSlash(trailingSlash: AstroConfig['trailingSlash'], buildFormat: AstroConfig['build']['format']): boolean;
|
||||
export declare function i18nHasFallback(config: AstroConfig): boolean;
|
||||
export declare function encodeName(name: string): string;
|
||||
export declare function viteBuildReturnToRollupOutputs(viteBuildReturn: ViteBuildReturn): Rollup.RollupOutput[];
|
54
node_modules/astro/dist/core/build/util.js
generated
vendored
Normal file
54
node_modules/astro/dist/core/build/util.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
function getTimeStat(timeStart, timeEnd) {
|
||||
const buildTime = timeEnd - timeStart;
|
||||
return buildTime < 1e3 ? `${Math.round(buildTime)}ms` : `${(buildTime / 1e3).toFixed(2)}s`;
|
||||
}
|
||||
function shouldAppendForwardSlash(trailingSlash, buildFormat) {
|
||||
switch (trailingSlash) {
|
||||
case "always":
|
||||
return true;
|
||||
case "never":
|
||||
return false;
|
||||
case "ignore": {
|
||||
switch (buildFormat) {
|
||||
case "directory":
|
||||
return true;
|
||||
case "preserve":
|
||||
case "file":
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function i18nHasFallback(config) {
|
||||
if (config.i18n && config.i18n.fallback) {
|
||||
return Object.keys(config.i18n.fallback).length > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function encodeName(name) {
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
if (name[i] === "%") {
|
||||
const third = name.codePointAt(i + 2) | 32;
|
||||
if (name[i + 1] !== "2" || third !== 102) {
|
||||
return `${name.replace(/%/g, "_percent_")}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
function viteBuildReturnToRollupOutputs(viteBuildReturn) {
|
||||
const result = [];
|
||||
if (Array.isArray(viteBuildReturn)) {
|
||||
result.push(...viteBuildReturn);
|
||||
} else if ("output" in viteBuildReturn) {
|
||||
result.push(viteBuildReturn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export {
|
||||
encodeName,
|
||||
getTimeStat,
|
||||
i18nHasFallback,
|
||||
shouldAppendForwardSlash,
|
||||
viteBuildReturnToRollupOutputs
|
||||
};
|
4
node_modules/astro/dist/core/client-directive/build.d.ts
generated
vendored
Normal file
4
node_modules/astro/dist/core/client-directive/build.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Build a client directive entrypoint into code that can directly run in a `<script>` tag.
|
||||
*/
|
||||
export declare function buildClientDirectiveEntrypoint(name: string, entrypoint: string, root: URL): Promise<string>;
|
27
node_modules/astro/dist/core/client-directive/build.js
generated
vendored
Normal file
27
node_modules/astro/dist/core/client-directive/build.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { build } from "esbuild";
|
||||
async function buildClientDirectiveEntrypoint(name, entrypoint, root) {
|
||||
const stringifiedName = JSON.stringify(name);
|
||||
const stringifiedEntrypoint = JSON.stringify(entrypoint);
|
||||
const output = await build({
|
||||
stdin: {
|
||||
contents: `import directive from ${stringifiedEntrypoint};
|
||||
|
||||
(self.Astro || (self.Astro = {}))[${stringifiedName}] = directive;
|
||||
|
||||
window.dispatchEvent(new Event('astro:' + ${stringifiedName}));`,
|
||||
resolveDir: fileURLToPath(root)
|
||||
},
|
||||
absWorkingDir: fileURLToPath(root),
|
||||
format: "iife",
|
||||
minify: true,
|
||||
bundle: true,
|
||||
write: false
|
||||
});
|
||||
const outputFile = output.outputFiles?.[0];
|
||||
if (!outputFile) return "";
|
||||
return outputFile.text;
|
||||
}
|
||||
export {
|
||||
buildClientDirectiveEntrypoint
|
||||
};
|
1
node_modules/astro/dist/core/client-directive/default.d.ts
generated
vendored
Normal file
1
node_modules/astro/dist/core/client-directive/default.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function getDefaultClientDirectives(): Map<string, string>;
|
17
node_modules/astro/dist/core/client-directive/default.js
generated
vendored
Normal file
17
node_modules/astro/dist/core/client-directive/default.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import idlePrebuilt from "../../runtime/client/idle.prebuilt.js";
|
||||
import loadPrebuilt from "../../runtime/client/load.prebuilt.js";
|
||||
import mediaPrebuilt from "../../runtime/client/media.prebuilt.js";
|
||||
import onlyPrebuilt from "../../runtime/client/only.prebuilt.js";
|
||||
import visiblePrebuilt from "../../runtime/client/visible.prebuilt.js";
|
||||
function getDefaultClientDirectives() {
|
||||
return /* @__PURE__ */ new Map([
|
||||
["idle", idlePrebuilt],
|
||||
["load", loadPrebuilt],
|
||||
["media", mediaPrebuilt],
|
||||
["only", onlyPrebuilt],
|
||||
["visible", visiblePrebuilt]
|
||||
]);
|
||||
}
|
||||
export {
|
||||
getDefaultClientDirectives
|
||||
};
|
2
node_modules/astro/dist/core/client-directive/index.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/client-directive/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export { buildClientDirectiveEntrypoint } from './build.js';
|
||||
export { getDefaultClientDirectives } from './default.js';
|
6
node_modules/astro/dist/core/client-directive/index.js
generated
vendored
Normal file
6
node_modules/astro/dist/core/client-directive/index.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { buildClientDirectiveEntrypoint } from "./build.js";
|
||||
import { getDefaultClientDirectives } from "./default.js";
|
||||
export {
|
||||
buildClientDirectiveEntrypoint,
|
||||
getDefaultClientDirectives
|
||||
};
|
16
node_modules/astro/dist/core/compile/compile.d.ts
generated
vendored
Normal file
16
node_modules/astro/dist/core/compile/compile.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { TransformResult } from '@astrojs/compiler';
|
||||
import type { ResolvedConfig } from 'vite';
|
||||
import type { AstroConfig } from '../../@types/astro.js';
|
||||
import type { AstroPreferences } from '../../preferences/index.js';
|
||||
import type { CompileCssResult } from './types.js';
|
||||
export interface CompileProps {
|
||||
astroConfig: AstroConfig;
|
||||
viteConfig: ResolvedConfig;
|
||||
preferences: AstroPreferences;
|
||||
filename: string;
|
||||
source: string;
|
||||
}
|
||||
export interface CompileResult extends Omit<TransformResult, 'css'> {
|
||||
css: CompileCssResult[];
|
||||
}
|
||||
export declare function compile({ astroConfig, viteConfig, preferences, filename, source, }: CompileProps): Promise<CompileResult>;
|
101
node_modules/astro/dist/core/compile/compile.js
generated
vendored
Normal file
101
node_modules/astro/dist/core/compile/compile.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { transform } from "@astrojs/compiler";
|
||||
import { normalizePath } from "vite";
|
||||
import { AggregateError, CompilerError } from "../errors/errors.js";
|
||||
import { AstroErrorData } from "../errors/index.js";
|
||||
import { resolvePath } from "../viteUtils.js";
|
||||
import { createStylePreprocessor } from "./style.js";
|
||||
async function compile({
|
||||
astroConfig,
|
||||
viteConfig,
|
||||
preferences,
|
||||
filename,
|
||||
source
|
||||
}) {
|
||||
const cssPartialCompileResults = [];
|
||||
const cssTransformErrors = [];
|
||||
let transformResult;
|
||||
try {
|
||||
transformResult = await transform(source, {
|
||||
compact: astroConfig.compressHTML,
|
||||
filename,
|
||||
normalizedFilename: normalizeFilename(filename, astroConfig.root),
|
||||
sourcemap: "both",
|
||||
internalURL: "astro/compiler-runtime",
|
||||
// TODO: this is no longer necessary for `Astro.site`
|
||||
// but it somehow allows working around caching issues in content collections for some tests
|
||||
astroGlobalArgs: JSON.stringify(astroConfig.site),
|
||||
scopedStyleStrategy: astroConfig.scopedStyleStrategy,
|
||||
resultScopedSlot: true,
|
||||
transitionsAnimationURL: "astro/components/viewtransitions.css",
|
||||
annotateSourceFile: viteConfig.command === "serve" && astroConfig.devToolbar && astroConfig.devToolbar.enabled && await preferences.get("devToolbar.enabled"),
|
||||
renderScript: astroConfig.experimental.directRenderScript,
|
||||
preprocessStyle: createStylePreprocessor({
|
||||
filename,
|
||||
viteConfig,
|
||||
cssPartialCompileResults,
|
||||
cssTransformErrors
|
||||
}),
|
||||
async resolvePath(specifier) {
|
||||
return resolvePath(specifier, filename);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
throw new CompilerError({
|
||||
...AstroErrorData.UnknownCompilerError,
|
||||
message: err.message ?? "Unknown compiler error",
|
||||
stack: err.stack,
|
||||
location: {
|
||||
file: filename
|
||||
}
|
||||
});
|
||||
}
|
||||
handleCompileResultErrors(transformResult, cssTransformErrors);
|
||||
return {
|
||||
...transformResult,
|
||||
css: transformResult.css.map((code, i) => ({
|
||||
...cssPartialCompileResults[i],
|
||||
code
|
||||
}))
|
||||
};
|
||||
}
|
||||
function handleCompileResultErrors(result, cssTransformErrors) {
|
||||
const compilerError = result.diagnostics.find((diag) => diag.severity === 1);
|
||||
if (compilerError) {
|
||||
throw new CompilerError({
|
||||
name: "CompilerError",
|
||||
message: compilerError.text,
|
||||
location: {
|
||||
line: compilerError.location.line,
|
||||
column: compilerError.location.column,
|
||||
file: compilerError.location.file
|
||||
},
|
||||
hint: compilerError.hint
|
||||
});
|
||||
}
|
||||
switch (cssTransformErrors.length) {
|
||||
case 0:
|
||||
break;
|
||||
case 1: {
|
||||
throw cssTransformErrors[0];
|
||||
}
|
||||
default: {
|
||||
throw new AggregateError({
|
||||
...cssTransformErrors[0],
|
||||
errors: cssTransformErrors
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function normalizeFilename(filename, root) {
|
||||
const normalizedFilename = normalizePath(filename);
|
||||
const normalizedRoot = normalizePath(fileURLToPath(root));
|
||||
if (normalizedFilename.startsWith(normalizedRoot)) {
|
||||
return normalizedFilename.slice(normalizedRoot.length - 1);
|
||||
} else {
|
||||
return normalizedFilename;
|
||||
}
|
||||
}
|
||||
export {
|
||||
compile
|
||||
};
|
2
node_modules/astro/dist/core/compile/index.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/core/compile/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export { compile } from './compile.js';
|
||||
export type { CompileProps, CompileResult } from './compile.js';
|
4
node_modules/astro/dist/core/compile/index.js
generated
vendored
Normal file
4
node_modules/astro/dist/core/compile/index.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { compile } from "./compile.js";
|
||||
export {
|
||||
compile
|
||||
};
|
10
node_modules/astro/dist/core/compile/style.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/core/compile/style.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { TransformOptions } from '@astrojs/compiler';
|
||||
import { type ResolvedConfig } from 'vite';
|
||||
import type { CompileCssResult } from './types.js';
|
||||
export type PartialCompileCssResult = Pick<CompileCssResult, 'isGlobal' | 'dependencies'>;
|
||||
export declare function createStylePreprocessor({ filename, viteConfig, cssPartialCompileResults, cssTransformErrors, }: {
|
||||
filename: string;
|
||||
viteConfig: ResolvedConfig;
|
||||
cssPartialCompileResults: Partial<CompileCssResult>[];
|
||||
cssTransformErrors: Error[];
|
||||
}): TransformOptions['preprocessStyle'];
|
86
node_modules/astro/dist/core/compile/style.js
generated
vendored
Normal file
86
node_modules/astro/dist/core/compile/style.js
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
import fs from "node:fs";
|
||||
import { normalizePath, preprocessCSS } from "vite";
|
||||
import { AstroErrorData, CSSError, positionAt } from "../errors/index.js";
|
||||
function createStylePreprocessor({
|
||||
filename,
|
||||
viteConfig,
|
||||
cssPartialCompileResults,
|
||||
cssTransformErrors
|
||||
}) {
|
||||
let processedStylesCount = 0;
|
||||
return async (content, attrs) => {
|
||||
const index = processedStylesCount++;
|
||||
const lang = `.${attrs?.lang || "css"}`.toLowerCase();
|
||||
const id = `${filename}?astro&type=style&index=${index}&lang${lang}`;
|
||||
try {
|
||||
const result = await preprocessCSS(content, id, viteConfig);
|
||||
cssPartialCompileResults[index] = {
|
||||
isGlobal: !!attrs["is:global"],
|
||||
dependencies: result.deps ? [...result.deps].map((dep) => normalizePath(dep)) : []
|
||||
};
|
||||
let map;
|
||||
if (result.map) {
|
||||
if (typeof result.map === "string") {
|
||||
map = result.map;
|
||||
} else if (result.map.mappings) {
|
||||
map = result.map.toString();
|
||||
}
|
||||
}
|
||||
return { code: result.code, map };
|
||||
} catch (err) {
|
||||
try {
|
||||
err = enhanceCSSError(err, filename, content);
|
||||
} catch {
|
||||
}
|
||||
cssTransformErrors.push(err);
|
||||
return { error: err + "" };
|
||||
}
|
||||
};
|
||||
}
|
||||
function enhanceCSSError(err, filename, cssContent) {
|
||||
const fileContent = fs.readFileSync(filename).toString();
|
||||
const styleTagBeginning = fileContent.indexOf(cssContent);
|
||||
if (err.name === "CssSyntaxError") {
|
||||
const errorLine = positionAt(styleTagBeginning, fileContent).line + (err.line ?? 0);
|
||||
return new CSSError({
|
||||
...AstroErrorData.CSSSyntaxError,
|
||||
message: err.reason,
|
||||
location: {
|
||||
file: filename,
|
||||
line: errorLine,
|
||||
column: err.column
|
||||
},
|
||||
stack: err.stack
|
||||
});
|
||||
}
|
||||
if (err.line && err.column) {
|
||||
const errorLine = positionAt(styleTagBeginning, fileContent).line + (err.line ?? 0);
|
||||
return new CSSError({
|
||||
...AstroErrorData.UnknownCSSError,
|
||||
message: err.message,
|
||||
location: {
|
||||
file: filename,
|
||||
line: errorLine,
|
||||
column: err.column
|
||||
},
|
||||
frame: err.frame,
|
||||
stack: err.stack
|
||||
});
|
||||
}
|
||||
const errorPosition = positionAt(styleTagBeginning, fileContent);
|
||||
errorPosition.line += 1;
|
||||
return new CSSError({
|
||||
name: "CSSError",
|
||||
message: err.message,
|
||||
location: {
|
||||
file: filename,
|
||||
line: errorPosition.line,
|
||||
column: 0
|
||||
},
|
||||
frame: err.frame,
|
||||
stack: err.stack
|
||||
});
|
||||
}
|
||||
export {
|
||||
createStylePreprocessor
|
||||
};
|
11
node_modules/astro/dist/core/compile/types.d.ts
generated
vendored
Normal file
11
node_modules/astro/dist/core/compile/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface CompileCssResult {
|
||||
code: string;
|
||||
/**
|
||||
* Whether this is `<style is:global>`
|
||||
*/
|
||||
isGlobal: boolean;
|
||||
/**
|
||||
* The dependencies of the transformed CSS (Normalized/forward-slash-only absolute paths)
|
||||
*/
|
||||
dependencies: string[];
|
||||
}
|
0
node_modules/astro/dist/core/compile/types.js
generated
vendored
Normal file
0
node_modules/astro/dist/core/compile/types.js
generated
vendored
Normal file
25
node_modules/astro/dist/core/config/config.d.ts
generated
vendored
Normal file
25
node_modules/astro/dist/core/config/config.d.ts
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import fs from 'node:fs';
|
||||
import type { AstroConfig, AstroInlineConfig, AstroUserConfig } from '../../@types/astro.js';
|
||||
export declare function resolveRoot(cwd?: string | URL): string;
|
||||
export declare const configPaths: readonly string[];
|
||||
interface ResolveConfigPathOptions {
|
||||
root: string;
|
||||
configFile?: string | false;
|
||||
fs: typeof fs;
|
||||
}
|
||||
/**
|
||||
* Resolve the file URL of the user's `astro.config.js|cjs|mjs|ts` file
|
||||
*/
|
||||
export declare function resolveConfigPath(options: ResolveConfigPathOptions): Promise<string | undefined>;
|
||||
interface ResolveConfigResult {
|
||||
userConfig: AstroUserConfig;
|
||||
astroConfig: AstroConfig;
|
||||
}
|
||||
/**
|
||||
* Resolves the Astro config with a given inline config.
|
||||
*
|
||||
* @param inlineConfig An inline config that takes highest priority when merging and resolving the final config.
|
||||
* @param command The running command that uses this config. Usually 'dev' or 'build'.
|
||||
*/
|
||||
export declare function resolveConfig(inlineConfig: AstroInlineConfig, command: string, fsMod?: typeof fs): Promise<ResolveConfigResult>;
|
||||
export {};
|
108
node_modules/astro/dist/core/config/config.js
generated
vendored
Normal file
108
node_modules/astro/dist/core/config/config.js
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import * as colors from "kleur/colors";
|
||||
import { ZodError } from "zod";
|
||||
import { eventConfigError, telemetry } from "../../events/index.js";
|
||||
import { trackAstroConfigZodError } from "../errors/errors.js";
|
||||
import { AstroError, AstroErrorData } from "../errors/index.js";
|
||||
import { formatConfigErrorMessage } from "../messages.js";
|
||||
import { mergeConfig } from "./merge.js";
|
||||
import { validateConfig } from "./validate.js";
|
||||
import { loadConfigWithVite } from "./vite-load.js";
|
||||
function resolveRoot(cwd) {
|
||||
if (cwd instanceof URL) {
|
||||
cwd = fileURLToPath(cwd);
|
||||
}
|
||||
return cwd ? path.resolve(cwd) : process.cwd();
|
||||
}
|
||||
const configPaths = Object.freeze([
|
||||
"astro.config.mjs",
|
||||
"astro.config.js",
|
||||
"astro.config.ts",
|
||||
"astro.config.mts",
|
||||
"astro.config.cjs",
|
||||
"astro.config.cts"
|
||||
]);
|
||||
async function search(fsMod, root) {
|
||||
const paths = configPaths.map((p) => path.join(root, p));
|
||||
for (const file of paths) {
|
||||
if (fsMod.existsSync(file)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
async function resolveConfigPath(options) {
|
||||
let userConfigPath;
|
||||
if (options.configFile) {
|
||||
userConfigPath = path.join(options.root, options.configFile);
|
||||
if (!options.fs.existsSync(userConfigPath)) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ConfigNotFound,
|
||||
message: AstroErrorData.ConfigNotFound.message(options.configFile)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
userConfigPath = await search(options.fs, options.root);
|
||||
}
|
||||
return userConfigPath;
|
||||
}
|
||||
async function loadConfig(root, configFile, fsMod = fs) {
|
||||
if (configFile === false) return {};
|
||||
const configPath = await resolveConfigPath({
|
||||
root,
|
||||
configFile,
|
||||
fs: fsMod
|
||||
});
|
||||
if (!configPath) return {};
|
||||
try {
|
||||
return await loadConfigWithVite({
|
||||
root,
|
||||
configPath,
|
||||
fs: fsMod
|
||||
});
|
||||
} catch (e) {
|
||||
const configPathText = configFile ? colors.bold(configFile) : "your Astro config";
|
||||
console.error(`${colors.bold(colors.red("[astro]"))} Unable to load ${configPathText}
|
||||
`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
function splitInlineConfig(inlineConfig) {
|
||||
const { configFile, mode, logLevel, ...inlineUserConfig } = inlineConfig;
|
||||
return {
|
||||
inlineUserConfig,
|
||||
inlineOnlyConfig: {
|
||||
configFile,
|
||||
mode,
|
||||
logLevel
|
||||
}
|
||||
};
|
||||
}
|
||||
async function resolveConfig(inlineConfig, command, fsMod = fs) {
|
||||
const root = resolveRoot(inlineConfig.root);
|
||||
const { inlineUserConfig, inlineOnlyConfig } = splitInlineConfig(inlineConfig);
|
||||
if (inlineConfig.root) {
|
||||
inlineUserConfig.root = root;
|
||||
}
|
||||
const userConfig = await loadConfig(root, inlineOnlyConfig.configFile, fsMod);
|
||||
const mergedConfig = mergeConfig(userConfig, inlineUserConfig);
|
||||
let astroConfig;
|
||||
try {
|
||||
astroConfig = await validateConfig(mergedConfig, root, command);
|
||||
} catch (e) {
|
||||
if (e instanceof ZodError) {
|
||||
trackAstroConfigZodError(e);
|
||||
console.error(formatConfigErrorMessage(e) + "\n");
|
||||
telemetry.record(eventConfigError({ cmd: command, err: e, isFatal: true }));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return { userConfig: mergedConfig, astroConfig };
|
||||
}
|
||||
export {
|
||||
configPaths,
|
||||
resolveConfig,
|
||||
resolveConfigPath,
|
||||
resolveRoot
|
||||
};
|
6
node_modules/astro/dist/core/config/index.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/core/config/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export { configPaths, resolveConfig, resolveConfigPath, resolveRoot, } from './config.js';
|
||||
export { createNodeLogger } from './logging.js';
|
||||
export { mergeConfig } from './merge.js';
|
||||
export type { AstroConfigType } from './schema.js';
|
||||
export { createSettings } from './settings.js';
|
||||
export { loadTSConfig, updateTSConfigForFramework } from './tsconfig.js';
|
21
node_modules/astro/dist/core/config/index.js
generated
vendored
Normal file
21
node_modules/astro/dist/core/config/index.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
configPaths,
|
||||
resolveConfig,
|
||||
resolveConfigPath,
|
||||
resolveRoot
|
||||
} from "./config.js";
|
||||
import { createNodeLogger } from "./logging.js";
|
||||
import { mergeConfig } from "./merge.js";
|
||||
import { createSettings } from "./settings.js";
|
||||
import { loadTSConfig, updateTSConfigForFramework } from "./tsconfig.js";
|
||||
export {
|
||||
configPaths,
|
||||
createNodeLogger,
|
||||
createSettings,
|
||||
loadTSConfig,
|
||||
mergeConfig,
|
||||
resolveConfig,
|
||||
resolveConfigPath,
|
||||
resolveRoot,
|
||||
updateTSConfigForFramework
|
||||
};
|
3
node_modules/astro/dist/core/config/logging.d.ts
generated
vendored
Normal file
3
node_modules/astro/dist/core/config/logging.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { AstroInlineConfig } from '../../@types/astro.js';
|
||||
import { Logger } from '../logger/core.js';
|
||||
export declare function createNodeLogger(inlineConfig: AstroInlineConfig): Logger;
|
12
node_modules/astro/dist/core/config/logging.js
generated
vendored
Normal file
12
node_modules/astro/dist/core/config/logging.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Logger } from "../logger/core.js";
|
||||
import { nodeLogDestination } from "../logger/node.js";
|
||||
function createNodeLogger(inlineConfig) {
|
||||
if (inlineConfig.logger) return inlineConfig.logger;
|
||||
return new Logger({
|
||||
dest: nodeLogDestination,
|
||||
level: inlineConfig.logLevel ?? "info"
|
||||
});
|
||||
}
|
||||
export {
|
||||
createNodeLogger
|
||||
};
|
1
node_modules/astro/dist/core/config/merge.d.ts
generated
vendored
Normal file
1
node_modules/astro/dist/core/config/merge.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
|
55
node_modules/astro/dist/core/config/merge.js
generated
vendored
Normal file
55
node_modules/astro/dist/core/config/merge.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { mergeConfig as mergeViteConfig } from "vite";
|
||||
import { arraify, isObject, isURL } from "../util.js";
|
||||
function mergeConfigRecursively(defaults, overrides, rootPath) {
|
||||
const merged = { ...defaults };
|
||||
for (const key in overrides) {
|
||||
const value = overrides[key];
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
let existing = merged[key];
|
||||
if (existing == null) {
|
||||
merged[key] = value;
|
||||
continue;
|
||||
}
|
||||
if (key === "vite" && rootPath === "") {
|
||||
merged[key] = mergeViteConfig(existing, value);
|
||||
continue;
|
||||
}
|
||||
if (key === "server" && rootPath === "") {
|
||||
if (typeof existing === "function" || typeof value === "function") {
|
||||
merged[key] = (...args) => {
|
||||
const existingConfig = typeof existing === "function" ? existing(...args) : existing;
|
||||
const valueConfig = typeof value === "function" ? value(...args) : value;
|
||||
return mergeConfigRecursively(existingConfig, valueConfig, key);
|
||||
};
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (key === "data" && rootPath === "db") {
|
||||
if (!Array.isArray(existing) && !Array.isArray(value)) {
|
||||
existing = [existing];
|
||||
}
|
||||
}
|
||||
if (Array.isArray(existing) || Array.isArray(value)) {
|
||||
merged[key] = [...arraify(existing ?? []), ...arraify(value ?? [])];
|
||||
continue;
|
||||
}
|
||||
if (isURL(existing) && isURL(value)) {
|
||||
merged[key] = value;
|
||||
continue;
|
||||
}
|
||||
if (isObject(existing) && isObject(value)) {
|
||||
merged[key] = mergeConfigRecursively(existing, value, rootPath ? `${rootPath}.${key}` : key);
|
||||
continue;
|
||||
}
|
||||
merged[key] = value;
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
function mergeConfig(defaults, overrides, isRoot = true) {
|
||||
return mergeConfigRecursively(defaults, overrides, isRoot ? "" : ".");
|
||||
}
|
||||
export {
|
||||
mergeConfig
|
||||
};
|
2983
node_modules/astro/dist/core/config/schema.d.ts
generated
vendored
Normal file
2983
node_modules/astro/dist/core/config/schema.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
446
node_modules/astro/dist/core/config/schema.js
generated
vendored
Normal file
446
node_modules/astro/dist/core/config/schema.js
generated
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
import { markdownConfigDefaults } from "@astrojs/markdown-remark";
|
||||
import { bundledThemes } from "shiki";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { z } from "zod";
|
||||
import { EnvSchema } from "../../env/schema.js";
|
||||
import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from "../path.js";
|
||||
const ASTRO_CONFIG_DEFAULTS = {
|
||||
root: ".",
|
||||
srcDir: "./src",
|
||||
publicDir: "./public",
|
||||
outDir: "./dist",
|
||||
cacheDir: "./node_modules/.astro",
|
||||
base: "/",
|
||||
trailingSlash: "ignore",
|
||||
build: {
|
||||
format: "directory",
|
||||
client: "./dist/client/",
|
||||
server: "./dist/server/",
|
||||
assets: "_astro",
|
||||
serverEntry: "entry.mjs",
|
||||
redirects: true,
|
||||
inlineStylesheets: "auto",
|
||||
concurrency: 1
|
||||
},
|
||||
image: {
|
||||
service: { entrypoint: "astro/assets/services/sharp", config: {} }
|
||||
},
|
||||
devToolbar: {
|
||||
enabled: true
|
||||
},
|
||||
compressHTML: true,
|
||||
server: {
|
||||
host: false,
|
||||
port: 4321,
|
||||
open: false
|
||||
},
|
||||
integrations: [],
|
||||
markdown: markdownConfigDefaults,
|
||||
vite: {},
|
||||
legacy: {},
|
||||
redirects: {},
|
||||
security: {},
|
||||
experimental: {
|
||||
directRenderScript: false,
|
||||
contentCollectionCache: false,
|
||||
clientPrerender: false,
|
||||
globalRoutePriority: false,
|
||||
serverIslands: false,
|
||||
contentIntellisense: false,
|
||||
env: {
|
||||
validateSecrets: false
|
||||
},
|
||||
contentLayer: false
|
||||
}
|
||||
};
|
||||
const AstroConfigSchema = z.object({
|
||||
root: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.root).transform((val) => new URL(val)),
|
||||
srcDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.srcDir).transform((val) => new URL(val)),
|
||||
publicDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.publicDir).transform((val) => new URL(val)),
|
||||
outDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.outDir).transform((val) => new URL(val)),
|
||||
cacheDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.cacheDir).transform((val) => new URL(val)),
|
||||
site: z.string().url().optional(),
|
||||
compressHTML: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.compressHTML),
|
||||
base: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.base),
|
||||
trailingSlash: z.union([z.literal("always"), z.literal("never"), z.literal("ignore")]).optional().default(ASTRO_CONFIG_DEFAULTS.trailingSlash),
|
||||
output: z.union([z.literal("static"), z.literal("server"), z.literal("hybrid")]).optional().default("static"),
|
||||
scopedStyleStrategy: z.union([z.literal("where"), z.literal("class"), z.literal("attribute")]).optional().default("attribute"),
|
||||
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
|
||||
integrations: z.preprocess(
|
||||
// preprocess
|
||||
(val) => Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val,
|
||||
// validate
|
||||
z.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) })).default(ASTRO_CONFIG_DEFAULTS.integrations)
|
||||
),
|
||||
build: z.object({
|
||||
format: z.union([z.literal("file"), z.literal("directory"), z.literal("preserve")]).optional().default(ASTRO_CONFIG_DEFAULTS.build.format),
|
||||
client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val)),
|
||||
server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => new URL(val)),
|
||||
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
|
||||
assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()).refine(
|
||||
(value) => {
|
||||
if (value && typeof value !== "string") {
|
||||
if (!value.fallback) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: "The `fallback` is mandatory when defining the option as an object."
|
||||
}
|
||||
),
|
||||
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
|
||||
redirects: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.redirects),
|
||||
inlineStylesheets: z.enum(["always", "auto", "never"]).optional().default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
|
||||
concurrency: z.number().min(1).optional().default(ASTRO_CONFIG_DEFAULTS.build.concurrency)
|
||||
}).default({}),
|
||||
server: z.preprocess(
|
||||
// preprocess
|
||||
// NOTE: Uses the "error" command here because this is overwritten by the
|
||||
// individualized schema parser with the correct command.
|
||||
(val) => typeof val === "function" ? val({ command: "error" }) : val,
|
||||
// validate
|
||||
z.object({
|
||||
open: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
|
||||
host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
|
||||
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
|
||||
headers: z.custom().optional()
|
||||
}).default({})
|
||||
),
|
||||
redirects: z.record(
|
||||
z.string(),
|
||||
z.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
status: z.union([
|
||||
z.literal(300),
|
||||
z.literal(301),
|
||||
z.literal(302),
|
||||
z.literal(303),
|
||||
z.literal(304),
|
||||
z.literal(307),
|
||||
z.literal(308)
|
||||
]),
|
||||
destination: z.string()
|
||||
})
|
||||
])
|
||||
).default(ASTRO_CONFIG_DEFAULTS.redirects),
|
||||
prefetch: z.union([
|
||||
z.boolean(),
|
||||
z.object({
|
||||
prefetchAll: z.boolean().optional(),
|
||||
defaultStrategy: z.enum(["tap", "hover", "viewport", "load"]).optional()
|
||||
})
|
||||
]).optional(),
|
||||
image: z.object({
|
||||
endpoint: z.string().optional(),
|
||||
service: z.object({
|
||||
entrypoint: z.union([
|
||||
z.literal("astro/assets/services/sharp"),
|
||||
z.literal("astro/assets/services/squoosh"),
|
||||
z.string()
|
||||
]).default(ASTRO_CONFIG_DEFAULTS.image.service.entrypoint),
|
||||
config: z.record(z.any()).default({})
|
||||
}).default(ASTRO_CONFIG_DEFAULTS.image.service),
|
||||
domains: z.array(z.string()).default([]),
|
||||
remotePatterns: z.array(
|
||||
z.object({
|
||||
protocol: z.string().optional(),
|
||||
hostname: z.string().refine(
|
||||
(val) => !val.includes("*") || val.startsWith("*.") || val.startsWith("**."),
|
||||
{
|
||||
message: "wildcards can only be placed at the beginning of the hostname"
|
||||
}
|
||||
).optional(),
|
||||
port: z.string().optional(),
|
||||
pathname: z.string().refine((val) => !val.includes("*") || val.endsWith("/*") || val.endsWith("/**"), {
|
||||
message: "wildcards can only be placed at the end of a pathname"
|
||||
}).optional()
|
||||
})
|
||||
).default([])
|
||||
}).default(ASTRO_CONFIG_DEFAULTS.image),
|
||||
devToolbar: z.object({
|
||||
enabled: z.boolean().default(ASTRO_CONFIG_DEFAULTS.devToolbar.enabled)
|
||||
}).default(ASTRO_CONFIG_DEFAULTS.devToolbar),
|
||||
markdown: z.object({
|
||||
syntaxHighlight: z.union([z.literal("shiki"), z.literal("prism"), z.literal(false)]).default(ASTRO_CONFIG_DEFAULTS.markdown.syntaxHighlight),
|
||||
shikiConfig: z.object({
|
||||
langs: z.custom().array().transform((langs) => {
|
||||
for (const lang of langs) {
|
||||
if (typeof lang === "object") {
|
||||
if (lang.id) {
|
||||
lang.name = lang.id;
|
||||
}
|
||||
if (lang.grammar) {
|
||||
Object.assign(lang, lang.grammar);
|
||||
}
|
||||
}
|
||||
}
|
||||
return langs;
|
||||
}).default([]),
|
||||
langAlias: z.record(z.string(), z.string()).optional().default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.langAlias),
|
||||
theme: z.enum(Object.keys(bundledThemes)).or(z.custom()).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.theme),
|
||||
themes: z.record(
|
||||
z.enum(Object.keys(bundledThemes)).or(z.custom())
|
||||
).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.themes),
|
||||
defaultColor: z.union([z.literal("light"), z.literal("dark"), z.string(), z.literal(false)]).optional(),
|
||||
wrap: z.boolean().or(z.null()).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.wrap),
|
||||
transformers: z.custom().array().transform((transformers) => {
|
||||
for (const transformer of transformers) {
|
||||
if (transformer.token && !("span" in transformer)) {
|
||||
transformer.span = transformer.token;
|
||||
}
|
||||
}
|
||||
return transformers;
|
||||
}).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.transformers)
|
||||
}).default({}),
|
||||
remarkPlugins: z.union([
|
||||
z.string(),
|
||||
z.tuple([z.string(), z.any()]),
|
||||
z.custom((data) => typeof data === "function"),
|
||||
z.tuple([z.custom((data) => typeof data === "function"), z.any()])
|
||||
]).array().default(ASTRO_CONFIG_DEFAULTS.markdown.remarkPlugins),
|
||||
rehypePlugins: z.union([
|
||||
z.string(),
|
||||
z.tuple([z.string(), z.any()]),
|
||||
z.custom((data) => typeof data === "function"),
|
||||
z.tuple([z.custom((data) => typeof data === "function"), z.any()])
|
||||
]).array().default(ASTRO_CONFIG_DEFAULTS.markdown.rehypePlugins),
|
||||
remarkRehype: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype),
|
||||
gfm: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.gfm),
|
||||
smartypants: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.smartypants)
|
||||
}).default({}),
|
||||
vite: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.vite),
|
||||
i18n: z.optional(
|
||||
z.object({
|
||||
defaultLocale: z.string(),
|
||||
locales: z.array(
|
||||
z.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
path: z.string(),
|
||||
codes: z.string().array().nonempty()
|
||||
})
|
||||
])
|
||||
),
|
||||
domains: z.record(
|
||||
z.string(),
|
||||
z.string().url(
|
||||
"The domain value must be a valid URL, and it has to start with 'https' or 'http'."
|
||||
)
|
||||
).optional(),
|
||||
fallback: z.record(z.string(), z.string()).optional(),
|
||||
routing: z.literal("manual").or(
|
||||
z.object({
|
||||
prefixDefaultLocale: z.boolean().optional().default(false),
|
||||
redirectToDefaultLocale: z.boolean().optional().default(true),
|
||||
fallbackType: z.enum(["redirect", "rewrite"]).optional().default("redirect")
|
||||
}).refine(
|
||||
({ prefixDefaultLocale, redirectToDefaultLocale }) => {
|
||||
return !(prefixDefaultLocale === false && redirectToDefaultLocale === false);
|
||||
},
|
||||
{
|
||||
message: "The option `i18n.redirectToDefaultLocale` is only useful when the `i18n.prefixDefaultLocale` is set to `true`. Remove the option `i18n.redirectToDefaultLocale`, or change its value to `true`."
|
||||
}
|
||||
)
|
||||
).optional().default({})
|
||||
}).optional().superRefine((i18n, ctx) => {
|
||||
if (i18n) {
|
||||
const { defaultLocale, locales: _locales, fallback, domains } = i18n;
|
||||
const locales = _locales.map((locale) => {
|
||||
if (typeof locale === "string") {
|
||||
return locale;
|
||||
} else {
|
||||
return locale.path;
|
||||
}
|
||||
});
|
||||
if (!locales.includes(defaultLocale)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`
|
||||
});
|
||||
}
|
||||
if (fallback) {
|
||||
for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) {
|
||||
if (!locales.includes(fallbackFrom)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`
|
||||
});
|
||||
}
|
||||
if (fallbackFrom === defaultLocale) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `You can't use the default locale as a key. The default locale can only be used as value.`
|
||||
});
|
||||
}
|
||||
if (!locales.includes(fallbackTo)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (domains) {
|
||||
const entries = Object.entries(domains);
|
||||
const hasDomains = domains ? Object.keys(domains).length > 0 : false;
|
||||
if (entries.length > 0 && !hasDomains) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `When specifying some domains, the property \`i18n.routingStrategy\` must be set to \`"domains"\`.`
|
||||
});
|
||||
}
|
||||
for (const [domainKey, domainValue] of entries) {
|
||||
if (!locales.includes(domainKey)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `The locale \`${domainKey}\` key in the \`i18n.domains\` record doesn't exist in the \`i18n.locales\` array.`
|
||||
});
|
||||
}
|
||||
if (!domainValue.startsWith("https") && !domainValue.startsWith("http")) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "The domain value must be a valid URL, and it has to start with 'https' or 'http'.",
|
||||
path: ["domains"]
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
const domainUrl = new URL(domainValue);
|
||||
if (domainUrl.pathname !== "/") {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `The URL \`${domainValue}\` must contain only the origin. A subsequent pathname isn't allowed here. Remove \`${domainUrl.pathname}\`.`,
|
||||
path: ["domains"]
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
),
|
||||
security: z.object({
|
||||
checkOrigin: z.boolean().default(false)
|
||||
}).optional().default(ASTRO_CONFIG_DEFAULTS.security),
|
||||
experimental: z.object({
|
||||
directRenderScript: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.directRenderScript),
|
||||
contentCollectionCache: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentCollectionCache),
|
||||
clientPrerender: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender),
|
||||
globalRoutePriority: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.globalRoutePriority),
|
||||
env: z.object({
|
||||
schema: EnvSchema.optional(),
|
||||
validateSecrets: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.env.validateSecrets)
|
||||
}).strict().optional(),
|
||||
serverIslands: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands),
|
||||
contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
|
||||
contentLayer: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentLayer)
|
||||
}).strict(
|
||||
`Invalid or outdated experimental feature.
|
||||
Check for incorrect spelling or outdated Astro version.
|
||||
See https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.`
|
||||
).default({}),
|
||||
legacy: z.object({}).default({})
|
||||
});
|
||||
function createRelativeSchema(cmd, fileProtocolRoot) {
|
||||
const AstroConfigRelativeSchema = AstroConfigSchema.extend({
|
||||
root: z.string().default(ASTRO_CONFIG_DEFAULTS.root).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
srcDir: z.string().default(ASTRO_CONFIG_DEFAULTS.srcDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
compressHTML: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.compressHTML),
|
||||
publicDir: z.string().default(ASTRO_CONFIG_DEFAULTS.publicDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
outDir: z.string().default(ASTRO_CONFIG_DEFAULTS.outDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
cacheDir: z.string().default(ASTRO_CONFIG_DEFAULTS.cacheDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
build: z.object({
|
||||
format: z.union([z.literal("file"), z.literal("directory"), z.literal("preserve")]).optional().default(ASTRO_CONFIG_DEFAULTS.build.format),
|
||||
client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
|
||||
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
|
||||
assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()).refine(
|
||||
(value) => {
|
||||
if (value && typeof value !== "string") {
|
||||
if (!value.fallback) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: "The `fallback` is mandatory when defining the option as an object."
|
||||
}
|
||||
),
|
||||
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
|
||||
redirects: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.redirects),
|
||||
inlineStylesheets: z.enum(["always", "auto", "never"]).optional().default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
|
||||
concurrency: z.number().min(1).optional().default(ASTRO_CONFIG_DEFAULTS.build.concurrency)
|
||||
}).optional().default({}),
|
||||
server: z.preprocess(
|
||||
// preprocess
|
||||
(val) => {
|
||||
if (typeof val === "function") {
|
||||
return val({ command: cmd === "dev" ? "dev" : "preview" });
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
},
|
||||
// validate
|
||||
z.object({
|
||||
open: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
|
||||
host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
|
||||
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
|
||||
headers: z.custom().optional(),
|
||||
streaming: z.boolean().optional().default(true)
|
||||
}).optional().default({})
|
||||
)
|
||||
}).transform((config) => {
|
||||
if (!config.build.server.toString().startsWith(config.outDir.toString()) && config.build.server.toString().endsWith("dist/server/")) {
|
||||
config.build.server = new URL("./dist/server/", config.outDir);
|
||||
}
|
||||
if (!config.build.client.toString().startsWith(config.outDir.toString()) && config.build.client.toString().endsWith("dist/client/")) {
|
||||
config.build.client = new URL("./dist/client/", config.outDir);
|
||||
}
|
||||
if (config.trailingSlash === "never") {
|
||||
config.base = prependForwardSlash(removeTrailingForwardSlash(config.base));
|
||||
} else if (config.trailingSlash === "always") {
|
||||
config.base = prependForwardSlash(appendForwardSlash(config.base));
|
||||
} else {
|
||||
config.base = prependForwardSlash(config.base);
|
||||
}
|
||||
return config;
|
||||
}).refine((obj) => !obj.outDir.toString().startsWith(obj.publicDir.toString()), {
|
||||
message: "The value of `outDir` must not point to a path within the folder set as `publicDir`, this will cause an infinite loop"
|
||||
}).superRefine((configuration, ctx) => {
|
||||
const { site, i18n, output } = configuration;
|
||||
const hasDomains = i18n?.domains ? Object.keys(i18n.domains).length > 0 : false;
|
||||
if (hasDomains) {
|
||||
if (!site) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "The option `site` isn't set. When using the 'domains' strategy for `i18n`, `site` is required to create absolute URLs for locales that aren't mapped to a domain."
|
||||
});
|
||||
}
|
||||
if (output !== "server") {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Domain support is only available when `output` is `"server"`.'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return AstroConfigRelativeSchema;
|
||||
}
|
||||
function resolveDirAsUrl(dir, root) {
|
||||
let resolvedDir = path.resolve(root, dir);
|
||||
if (!resolvedDir.endsWith(path.sep)) {
|
||||
resolvedDir += path.sep;
|
||||
}
|
||||
return pathToFileURL(resolvedDir);
|
||||
}
|
||||
export {
|
||||
ASTRO_CONFIG_DEFAULTS,
|
||||
AstroConfigSchema,
|
||||
createRelativeSchema
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user