import{File}from"file/classes";importJSFilefrom"./js.js";import{readFile}from"file";importHtmlPagefrom"../../html/builder";importtype{PageSettings}from"../../types/site";importtype{HtmlNode,PageSyntax}from"../../types/html";import{Path}from"../../utils/path";/** * Read a javascript file to string. */constreadJSFile=(path: Path,cfg: PageSettings)=>{returnnewJSFile(path,cfg);};constfolderIndexPageTable=({
files,
rootUrl,
sourceDir,}: {files: File[];rootUrl: string;sourceDir: string;}): PageSyntax=>{return["div",{class: "folder-index-page-table"},["table",files.map((childFile)=>{constlastLog=childFile.lastLog;return["tr",["td",{class: "file-hash-tr"},lastLog?.shortHash],["td",{class: "file-name-tr"},["a",{href: childFile.htmlUrl({
rootUrl,
sourceDir,}),},childFile.name,],],["td",{class: "file-type-tr"},childFile.extension],["td",{class: lastLog?.date ? "file-date-tr" : "file-date-untracked-tr",},lastLog?.date??"untracked",],];})asHtmlNode[],],];};constdirectoryToHtml=(dir: Directory,{
files,
rootUrl,
siteName,
sourceDir,
resourcesDir,
faviconsDir,}: PageSettings&{files: File[]}): PageSyntax=>{consttitle=dir.name;return["html",["Header",{ title, siteName, rootUrl, resourcesDir, faviconsDir }],["body",["Sidebar",{path: dir.path, title, sourceDir, rootUrl }],["div",{class: "site-body"},["main",folderIndexPageTable({ files, rootUrl, sourceDir }),["ScrollUp"],],],],];};/** * Represents a directory, which is a file that contains other files. */classDirectoryextendsFile{staticfiletypes=["dir"];privateenumeratedContents: File[]|undefined=undefined;privateenumeratedDependencies: File[]|undefined=undefined;privateenumeratedHtml: HtmlPage|undefined=undefined;/** * Recursively fetch and flatten the file tree. */tree(cfg: PageSettings){constmyContents=this.contents(cfg);constchildFiles: File[]=[];myContents.forEach((file)=>{if(file.isDirectory()){childFiles.push(...file.tree(cfg));}else{childFiles.push(file);}});returnchildFiles;}/** * Get all the files in the immediate directory. * This is not treated as a property and is not cached due to the possibility of files changing. * * @param {boolean} omitNonJSFiles - Flag to bootstrap the setup. The 'readFile' function dispatches based on this flag to force JavaScript files. */contents(cfg?: PageSettings,{ omitNonJSFiles =false}: {omitNonJSFiles: boolean}={omitNonJSFiles: false,}): File[]{// special case for the js files: make sure they all exist.// don't cache this because we only want the default full dir cached.if(omitNonJSFiles){constjsPaths=this.path.readDirectory();constmaybeJSFiles=jsPaths.map((childPath: Path)=>{if(childPath.extension!=="js"&&childPath.extension!=="ts"){returnundefined;}else{returnreadJSFile(childPath,this.cachedConfig);}});constretFiles: File[]=[];maybeJSFiles.forEach((f)=>{if(f){retFiles.push(f);}});returnretFiles;}if(this.enumeratedContents){returnthis.enumeratedContents;}constfileContents=this.path.readDirectory()// SHORTCUT: Fixes a bug where the site creates itself infinitely.filter((v)=>v.toString()!==this.cachedConfig.targetDir).map((v)=>readFile(v,this.cachedConfig));this.enumeratedContents=fileContents;returnfileContents;}/** * Given a file path relative to this directory, * find the relevant source file. */findFile(relativePath: Path,cfg: PageSettings){constpath=this.path.join(relativePath);try{returnreadFile(path,cfg);}catch(e){returnnull;}}htmlUrl({ sourceDir }: {sourceDir: string}){constrelativeToSource=this.path.relativeTo(sourceDir);returnrelativeToSource.toString()+"/index.html";}write(config: PageSettings){const{ sourceDir, targetDir }=config;// first, make sure the corresponding directory exists.// this is e.g. '/site/docs/' and mkdir /site/docs/consttargetPath=this.path.relativeTo(sourceDir,targetDir);targetPath.make({isDirectory: true});returnthis;}/** * Find all of the dependencies of a directory. * * The dependencies of a directory are all of the files that it contains, * but as html versions. this is a proxy for finding those links in the html * * SHORTCUT: the dependencies of a directory in general are not html-ified. * That's a quick hack we use here to bootstrap building files. */dependencies(settings: PageSettings){if(!this.enumeratedDependencies){this.enumeratedDependencies=this.asHtml(settings)?.dependencies();}returnthis.enumeratedDependencies;}/** * This is a directory, so we return true. */isDirectory(){returntrue;}/** * Render the directory as HTML, cacheing the rendering if necessary. */asHtml(settings: PageSettings){if(!this.enumeratedHtml){constfiles=this.contents(settings);constpage=directoryToHtml(this,{
files,
...settings,});this.enumeratedHtml=HtmlPage.create(page,settings);}returnthis.enumeratedHtml;}/** * Get the MIME type of this directory. * * SHORTCUT: As of now we only use folders for their HTML rendering, * so we always treat them as HTML files. */getmimeType(){return"text/html";}}exportdefaultDirectory;