import { promises as fs } from "fs" ; import path from "upath" ; import * as logger from "../shared/logger" ; import templates from "../templates" ; type Page = { name : string ; projectId : string ; path : string ; url : string ; } ; async function isUserManagedFile ( path ) { try { const content = await fs . readFile ( path ) ; return ! content . toString ( ) . startsWith ( "/** This file is auto-generated by Plasmic" ) ; } catch ( error ) { if ( error . code === "ENOENT" ) { return false ; } throw error ; } } let didWarnConflictingRoot = false ; let didWarnConflictingCatchAll = false ; async function syncIndexPage ( page , pageDir , fileExtension ) { const fileName = `index.${ fileExtension }` ; const filePath = path . join ( pageDir , fileName ) ; const managedByUser = await isUserManagedFile ( filePath ) ; if ( managedByUser ) { if ( page && ! didWarnConflictingRoot ) { logger . warn ( `Top-level ${ fileName } detected.\nPlasmic uses a catch-all file to register Plasmic pages. Because of this conflict, Plasmic wont register this page.` ) ; didWarnConflictingRoot = true ; } return ; } if ( ! page ) { try { await fs . unlink ( filePath ) ; } catch ( error ) { if ( error . code !== "ENOENT" ) { throw error ; } } return ; } await fs . writeFile ( filePath , templates . PlasmicPage ( { name : page . name , projectId : page . projectId , } ) ) ; } async function syncCatchAllPage ( pages , pageDir , fileExtension ) { if ( ! pages . length ) { return ; } const topLevelPages = await fs . readdir ( pageDir ) ; const catchAllFile = topLevelPages . find ( ( page ) => page . startsWith ( "[" ) ) ; if ( ! catchAllFile ) { const fileName = `[...plasmicLoaderPage].${ fileExtension }` ; const filePath = path . join ( pageDir , fileName ) ; await fs . writeFile ( filePath , templates . NextPage ( ) ) ; return ; } const catchAllContent = await fs . readFile ( path . join ( pageDir , catchAllFile ) ) . then ( ( content ) => content . toString ( ) ) ; const includesPagesFunction = catchAllContent . includes ( "getPageUrls" ) || catchAllContent . includes ( "getUnregisteredPageUrls" ) ; const includesLoaderImport = catchAllContent . includes ( "@plasmicapp/loader" ) ; if ( ! includesPagesFunction || ! includesLoaderImport ) { if ( ! didWarnConflictingCatchAll ) { logger . warn ( `To use PlasmicPages, please add it to your top-level catch-all "${ catchAllFile }".` + "\n\nHere's an example on how to do it in NextJS: https://github.com/plasmicapp/nextjs-starter/blob/master/pages/[...plasmicLoaderPage].js" + "\n\nAlternatively, you can remove this file." ) ; } didWarnConflictingCatchAll = true ; return ; } } export async function generateNextPages ( pages , dir , config ) { const extension = config . code . lang === "js" ? "js" : "tsx" ; const indexPage = pages . find ( ( page ) => page . url === "/" ) ; const otherPages = pages . filter ( ( page ) => page . url !== "/" ) ; await Promise . all ( [ syncIndexPage ( indexPage , dir , extension ) , syncCatchAllPage ( otherPages , dir , extension ) , ] ) ; }