import{Path}from"utils/path";importFilefrom"./classes/file";importDirectoryfrom"./filetype/directory";importTextFilefrom"file/classes/text";importJavascriptFilefrom"./filetype/js";importtype{PageSettings}from"../types/site";/* * A standard interface for interacting with files. * * Create a file with the provided path string * and the specific file class should handle the rest. * * Import all the files from the 'filetype' directory * and associate them with their filetype names. */typeFiletypeMap={[key: string]: typeofFile};letfiletypeMap: FiletypeMap;// obtain a map of file to filetypeconstgetFiletypeMap=(cfg: PageSettings)=>{// bootstrap the process; we know we have a directoryconstdir=newDirectory(Path.create(__dirname+"/filetype/"),cfg);constnewFiletypeMap: FiletypeMap={};// Problem: to bootstrap the process, we need to know what class// a file is before we can create it. but we need to create itdir.contents(cfg,{omitNonJSFiles: true}).map((file: File)=>{// because we have a js file, we know we can require itconstfileClass=(fileasJavascriptFile).require();// default to using the raw 'fileClass' if there is no default export (?)returnfileClass?.default??fileClass;}).forEach((fileClass)=>{if(!fileClass.filetypes){thrownewError(`Filetype ${fileClass.name} does not have a 'filetypes' property`);}fileClass.filetypes.forEach((fileType: string)=>{if(newFiletypeMap[fileType]){thrownewError(`Filetype ${fileType} already exists`);}newFiletypeMap[fileType]=fileClass;});});returnnewFiletypeMap;};constfileCache: {[key: string]: File}={};/** * Given the source path of a file, return the appropriate file class. * @param {string} incomingPath - The source path of the file. * @param {Object} options - Additional options. * @returns {Object} The appropriate file class. */constreadFile=(incomingPath: string|Path,options: PageSettings): File=>{if(!filetypeMap){filetypeMap=getFiletypeMap(options);}const{ sourceDir, fallbackSourceDir }=options??{};// Get the file extensionletpath=Path.create(incomingPath);// If the path doesn't exist, try it against a fallbackif(!path.exists()&&sourceDir&&fallbackSourceDir){path=path.relativeTo(sourceDir,fallbackSourceDir);}constextension=path.extension;if(!fileCache[path.toString()]){if(!extension||!(extensioninfiletypeMap)){console.log(`We don't have a filetype mapping for files with extension ${extension}. Assuming plaintext for file at path '${path.toString()}'.`);fileCache[path.toString()]=TextFile.create(path,options);}else{constFiletypeClass=filetypeMap[extension];fileCache[path.toString()]=FiletypeClass.create(path,options);}}returnfileCache[path.toString()];};export{readFile};