108 lines
2.8 KiB
Plaintext
108 lines
2.8 KiB
Plaintext
|
import { callEndpoint, createAPIContext } from "./endpoint/index.js";
|
||
|
import { callMiddleware } from "./middleware/callMiddleware.js";
|
||
|
import { renderPage } from "./render/core.js";
|
||
|
import {} from "./render/index.js";
|
||
|
class Pipeline {
|
||
|
env;
|
||
|
#onRequest;
|
||
|
#hooks = {
|
||
|
before: []
|
||
|
};
|
||
|
/**
|
||
|
* When creating a pipeline, an environment is mandatory.
|
||
|
* The environment won't change for the whole lifetime of the pipeline.
|
||
|
*/
|
||
|
constructor(env) {
|
||
|
this.env = env;
|
||
|
}
|
||
|
setEnvironment() {
|
||
|
}
|
||
|
/**
|
||
|
* A middleware function that will be called before each request.
|
||
|
*/
|
||
|
setMiddlewareFunction(onRequest) {
|
||
|
this.#onRequest = onRequest;
|
||
|
}
|
||
|
/**
|
||
|
* Removes the current middleware function. Subsequent requests won't trigger any middleware.
|
||
|
*/
|
||
|
unsetMiddlewareFunction() {
|
||
|
this.#onRequest = void 0;
|
||
|
}
|
||
|
/**
|
||
|
* Returns the current environment
|
||
|
*/
|
||
|
getEnvironment() {
|
||
|
return this.env;
|
||
|
}
|
||
|
/**
|
||
|
* The main function of the pipeline. Use this function to render any route known to Astro;
|
||
|
*/
|
||
|
async renderRoute(renderContext, componentInstance) {
|
||
|
for (const hook of this.#hooks.before) {
|
||
|
hook(renderContext, componentInstance);
|
||
|
}
|
||
|
return await this.#tryRenderRoute(renderContext, this.env, componentInstance, this.#onRequest);
|
||
|
}
|
||
|
/**
|
||
|
* It attempts to render a route. A route can be a:
|
||
|
* - page
|
||
|
* - redirect
|
||
|
* - endpoint
|
||
|
*
|
||
|
* ## Errors
|
||
|
*
|
||
|
* It throws an error if the page can't be rendered.
|
||
|
*/
|
||
|
async #tryRenderRoute(renderContext, env, mod, onRequest) {
|
||
|
const apiContext = createAPIContext({
|
||
|
request: renderContext.request,
|
||
|
params: renderContext.params,
|
||
|
props: renderContext.props,
|
||
|
site: env.site,
|
||
|
adapterName: env.adapterName,
|
||
|
locales: renderContext.locales,
|
||
|
routingStrategy: renderContext.routing,
|
||
|
defaultLocale: renderContext.defaultLocale
|
||
|
});
|
||
|
switch (renderContext.route.type) {
|
||
|
case "page":
|
||
|
case "fallback":
|
||
|
case "redirect": {
|
||
|
if (onRequest) {
|
||
|
return await callMiddleware(onRequest, apiContext, () => {
|
||
|
return renderPage({
|
||
|
mod,
|
||
|
renderContext,
|
||
|
env,
|
||
|
cookies: apiContext.cookies
|
||
|
});
|
||
|
});
|
||
|
} else {
|
||
|
return await renderPage({
|
||
|
mod,
|
||
|
renderContext,
|
||
|
env,
|
||
|
cookies: apiContext.cookies
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
case "endpoint": {
|
||
|
return await callEndpoint(mod, env, renderContext, onRequest);
|
||
|
}
|
||
|
default:
|
||
|
throw new Error(`Couldn't find route of type [${renderContext.route.type}]`);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Store a function that will be called before starting the rendering phase.
|
||
|
* @param fn
|
||
|
*/
|
||
|
onBeforeRenderRoute(fn) {
|
||
|
this.#hooks.before.push(fn);
|
||
|
}
|
||
|
}
|
||
|
export {
|
||
|
Pipeline
|
||
|
};
|