Add app, error, and document entrypoints (#53013)
### What adds endpoints for `_app` `_error` and `_document` for pages Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
This commit is contained in:
parent
c8eb7f3de0
commit
2cd0c8abc7
6 changed files with 146 additions and 39 deletions
|
@ -207,6 +207,9 @@ impl NapiMiddleware {
|
|||
struct NapiEntrypoints {
|
||||
pub routes: Vec<NapiRoute>,
|
||||
pub middleware: Option<NapiMiddleware>,
|
||||
pub pages_document_endpoint: External<ExternalEndpoint>,
|
||||
pub pages_app_endpoint: External<ExternalEndpoint>,
|
||||
pub pages_error_endpoint: External<ExternalEndpoint>,
|
||||
pub issues: Vec<NapiIssue>,
|
||||
pub diagnostics: Vec<NapiDiagnostic>,
|
||||
}
|
||||
|
@ -245,6 +248,18 @@ pub fn project_entrypoints_subscribe(
|
|||
.as_ref()
|
||||
.map(|m| NapiMiddleware::from_middleware(m, &turbo_tasks))
|
||||
.transpose()?,
|
||||
pages_document_endpoint: External::new(ExternalEndpoint(VcArc::new(
|
||||
turbo_tasks.clone(),
|
||||
entrypoints.pages_document_endpoint,
|
||||
))),
|
||||
pages_app_endpoint: External::new(ExternalEndpoint(VcArc::new(
|
||||
turbo_tasks.clone(),
|
||||
entrypoints.pages_app_endpoint,
|
||||
))),
|
||||
pages_error_endpoint: External::new(ExternalEndpoint(VcArc::new(
|
||||
turbo_tasks.clone(),
|
||||
entrypoints.pages_error_endpoint,
|
||||
))),
|
||||
issues: issues
|
||||
.iter()
|
||||
.map(|issue| NapiIssue::from(&**issue))
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
use indexmap::IndexMap;
|
||||
use turbo_tasks::Vc;
|
||||
|
||||
use crate::{project::Middleware, route::Route};
|
||||
use crate::{
|
||||
project::Middleware,
|
||||
route::{Endpoint, Route},
|
||||
};
|
||||
|
||||
#[turbo_tasks::value(shared)]
|
||||
pub struct Entrypoints {
|
||||
pub routes: IndexMap<String, Route>,
|
||||
pub middleware: Option<Middleware>,
|
||||
pub pages_document_endpoint: Vc<Box<dyn Endpoint>>,
|
||||
pub pages_app_endpoint: Vc<Box<dyn Endpoint>>,
|
||||
pub pages_error_endpoint: Vc<Box<dyn Endpoint>>,
|
||||
}
|
||||
|
|
|
@ -66,8 +66,33 @@ impl PagesProject {
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn routes(self: Vc<Self>) -> Result<Vc<Routes>> {
|
||||
let PagesStructure { api, pages, .. } = &*self.pages_structure().await?;
|
||||
let PagesStructure {
|
||||
api,
|
||||
pages,
|
||||
app: _,
|
||||
document: _,
|
||||
error: _,
|
||||
} = &*self.pages_structure().await?;
|
||||
let mut routes = IndexMap::new();
|
||||
|
||||
async fn add_page_to_routes(
|
||||
routes: &mut IndexMap<String, Route>,
|
||||
page: Vc<PagesStructureItem>,
|
||||
make_route: impl Fn(Vc<String>, Vc<String>, Vc<FileSystemPath>) -> Route,
|
||||
) -> Result<()> {
|
||||
let PagesStructureItem {
|
||||
next_router_path,
|
||||
project_path,
|
||||
original_path,
|
||||
} = *page.await?;
|
||||
let pathname = format!("/{}", next_router_path.await?.path);
|
||||
let pathname_vc = Vc::cell(pathname.clone());
|
||||
let original_name = Vc::cell(format!("/{}", original_path.await?.path));
|
||||
let route = make_route(pathname_vc, original_name, project_path);
|
||||
routes.insert(pathname, route);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_dir_to_routes(
|
||||
routes: &mut IndexMap<String, Route>,
|
||||
dir: Vc<PagesDirectoryStructure>,
|
||||
|
@ -82,16 +107,7 @@ impl PagesProject {
|
|||
project_path: _,
|
||||
} = *dir.await?;
|
||||
for &item in items.iter() {
|
||||
let PagesStructureItem {
|
||||
next_router_path,
|
||||
project_path,
|
||||
original_path,
|
||||
} = *item.await?;
|
||||
let pathname = format!("/{}", next_router_path.await?.path);
|
||||
let pathname_vc = Vc::cell(pathname.clone());
|
||||
let original_name = Vc::cell(format!("/{}", original_path.await?.path));
|
||||
let route = make_route(pathname_vc, original_name, project_path);
|
||||
routes.insert(pathname, route);
|
||||
add_page_to_routes(routes, item, &make_route).await?;
|
||||
}
|
||||
for &child in children.iter() {
|
||||
queue.push(child);
|
||||
|
@ -99,6 +115,7 @@ impl PagesProject {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if let Some(api) = api {
|
||||
add_dir_to_routes(&mut routes, *api, |pathname, original_name, path| {
|
||||
Route::PageApi {
|
||||
|
@ -113,30 +130,74 @@ impl PagesProject {
|
|||
})
|
||||
.await?;
|
||||
}
|
||||
if let Some(page) = pages {
|
||||
add_dir_to_routes(&mut routes, *page, |pathname, original_name, path| {
|
||||
Route::Page {
|
||||
html_endpoint: Vc::upcast(PageEndpoint::new(
|
||||
PageEndpointType::Html,
|
||||
self,
|
||||
pathname,
|
||||
original_name,
|
||||
path,
|
||||
)),
|
||||
data_endpoint: Vc::upcast(PageEndpoint::new(
|
||||
PageEndpointType::Data,
|
||||
self,
|
||||
pathname,
|
||||
original_name,
|
||||
path,
|
||||
)),
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
let make_page_route = |pathname, original_name, path| Route::Page {
|
||||
html_endpoint: Vc::upcast(PageEndpoint::new(
|
||||
PageEndpointType::Html,
|
||||
self,
|
||||
pathname,
|
||||
original_name,
|
||||
path,
|
||||
)),
|
||||
data_endpoint: Vc::upcast(PageEndpoint::new(
|
||||
PageEndpointType::Data,
|
||||
self,
|
||||
pathname,
|
||||
original_name,
|
||||
path,
|
||||
)),
|
||||
};
|
||||
|
||||
if let Some(pages) = pages {
|
||||
add_dir_to_routes(&mut routes, *pages, make_page_route).await?;
|
||||
}
|
||||
|
||||
Ok(Vc::cell(routes))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
async fn to_endpoint(
|
||||
self: Vc<Self>,
|
||||
item: Vc<PagesStructureItem>,
|
||||
ty: PageEndpointType,
|
||||
) -> Result<Vc<Box<dyn Endpoint>>> {
|
||||
let PagesStructureItem {
|
||||
next_router_path,
|
||||
project_path,
|
||||
original_path,
|
||||
} = *item.await?;
|
||||
let pathname = format!("/{}", next_router_path.await?.path);
|
||||
let pathname_vc = Vc::cell(pathname.clone());
|
||||
let original_name = Vc::cell(format!("/{}", original_path.await?.path));
|
||||
let path = project_path;
|
||||
let endpoint = Vc::upcast(PageEndpoint::new(
|
||||
ty,
|
||||
self,
|
||||
pathname_vc,
|
||||
original_name,
|
||||
path,
|
||||
));
|
||||
Ok(endpoint)
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn document_endpoint(self: Vc<Self>) -> Result<Vc<Box<dyn Endpoint>>> {
|
||||
Ok(self.to_endpoint(
|
||||
self.pages_structure().await?.document,
|
||||
PageEndpointType::SsrOnly,
|
||||
))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn app_endpoint(self: Vc<Self>) -> Result<Vc<Box<dyn Endpoint>>> {
|
||||
Ok(self.to_endpoint(self.pages_structure().await?.app, PageEndpointType::Html))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn error_endpoint(self: Vc<Self>) -> Result<Vc<Box<dyn Endpoint>>> {
|
||||
Ok(self.to_endpoint(self.pages_structure().await?.error, PageEndpointType::Html))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
fn project(&self) -> Vc<Project> {
|
||||
self.project
|
||||
|
@ -407,6 +468,7 @@ enum PageEndpointType {
|
|||
Api,
|
||||
Html,
|
||||
Data,
|
||||
SsrOnly,
|
||||
}
|
||||
|
||||
#[turbo_tasks::value_impl]
|
||||
|
@ -665,6 +727,7 @@ impl PageEndpoint {
|
|||
}
|
||||
PageEndpointType::Data => self.ssr_data_chunk(),
|
||||
PageEndpointType::Api => self.api_chunk(),
|
||||
PageEndpointType::SsrOnly => self.ssr_chunk(),
|
||||
};
|
||||
|
||||
let page_output = match *ssr_chunk.await? {
|
||||
|
|
|
@ -373,6 +373,9 @@ impl Project {
|
|||
Ok(Entrypoints {
|
||||
routes,
|
||||
middleware: None,
|
||||
pages_document_endpoint: self.pages_project().document_endpoint(),
|
||||
pages_app_endpoint: self.pages_project().app_endpoint(),
|
||||
pages_error_endpoint: self.pages_project().error_endpoint(),
|
||||
}
|
||||
.cell())
|
||||
}
|
||||
|
|
|
@ -393,6 +393,9 @@ interface Middleware {
|
|||
interface Entrypoints {
|
||||
routes: Map<string, Route>
|
||||
middleware?: Middleware
|
||||
pagesDocumentEndpoint: Endpoint
|
||||
pagesAppEndpoint: Endpoint
|
||||
pagesErrorEndpoint: Endpoint
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
@ -587,6 +590,9 @@ function bindingToApi(binding: any, _wasm: boolean) {
|
|||
type NapiEntrypoints = {
|
||||
routes: NapiRoute[]
|
||||
middleware?: NapiMiddleware
|
||||
pagesDocumentEndpoint: NapiEndpoint
|
||||
pagesAppEndpoint: NapiEndpoint
|
||||
pagesErrorEndpoint: NapiEndpoint
|
||||
issues: Issue[]
|
||||
diagnostics: Diagnostics[]
|
||||
}
|
||||
|
@ -683,6 +689,13 @@ function bindingToApi(binding: any, _wasm: boolean) {
|
|||
yield {
|
||||
routes,
|
||||
middleware,
|
||||
pagesDocumentEndpoint: new EndpointImpl(
|
||||
entrypoints.pagesDocumentEndpoint
|
||||
),
|
||||
pagesAppEndpoint: new EndpointImpl(entrypoints.pagesAppEndpoint),
|
||||
pagesErrorEndpoint: new EndpointImpl(
|
||||
entrypoints.pagesErrorEndpoint
|
||||
),
|
||||
issues: entrypoints.issues,
|
||||
diagnostics: entrypoints.diagnostics,
|
||||
}
|
||||
|
|
|
@ -240,20 +240,29 @@ const nextDev: CliCommand = async (argv) => {
|
|||
|
||||
// Just testing code here:
|
||||
|
||||
const project = await bindings.turbo.createProject({
|
||||
const options = {
|
||||
projectPath: dir,
|
||||
rootPath: dir,
|
||||
rootPath: args['--root'] ?? findRootDir(dir) ?? dir,
|
||||
nextConfig: config,
|
||||
env: {
|
||||
NEXT_PUBLIC_ENV_VAR: 'world',
|
||||
},
|
||||
watch: true,
|
||||
})
|
||||
}
|
||||
const project = await bindings.turbo.createProject(options)
|
||||
const iter = project.entrypointsSubscribe()
|
||||
|
||||
try {
|
||||
for await (const entrypoints of iter) {
|
||||
Log.info(entrypoints)
|
||||
|
||||
Log.info(`writing _document to disk`)
|
||||
Log.info(await entrypoints.pagesDocumentEndpoint.writeToDisk())
|
||||
Log.info(`writing _app to disk`)
|
||||
Log.info(await entrypoints.pagesAppEndpoint.writeToDisk())
|
||||
Log.info(`writing _error to disk`)
|
||||
Log.info(await entrypoints.pagesErrorEndpoint.writeToDisk())
|
||||
|
||||
for (const [pathname, route] of entrypoints.routes) {
|
||||
switch (route.type) {
|
||||
case 'page': {
|
||||
|
@ -287,13 +296,10 @@ const nextDev: CliCommand = async (argv) => {
|
|||
}
|
||||
Log.info('iteration done')
|
||||
await project.update({
|
||||
projectPath: dir,
|
||||
rootPath: dir,
|
||||
nextConfig: config,
|
||||
...options,
|
||||
env: {
|
||||
NEXT_PUBLIC_ENV_VAR: 'hello',
|
||||
},
|
||||
watch: true,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
Loading…
Reference in a new issue