import { basename, dirname, extname, fromFileUrl, join, resolve,} from "../deps.ts";
function tryStat(path: string) { try { return Deno.statSync(path); } catch (e) { return undefined; }}
function toPath(pathLike: string) { return pathLike.startsWith("file:") ? fromFileUrl(pathLike) : pathLike;}
export class View { defaultEngine!: any; ext!: any; name!: any; root!: any; engine!: any; path!: any;
constructor(fileName: string, options: any = {}) { this.defaultEngine = options.defaultEngine; this.ext = extname(fileName); this.name = fileName;
if (Array.isArray(options.root)) { this.root = options.root.map(toPath); } else { this.root = toPath(options.root); }
if (!this.ext && !this.defaultEngine) { throw new Error( "No default engine was specified and no extension was provided.", ); }
if (!this.ext) { this.ext = this.defaultEngine[0] !== "." ? `.${this.defaultEngine}` : this.defaultEngine;
fileName += this.ext; }
if (!options.engines[this.ext]) { throw new Error( `Could not find a view engine for extension "${this.ext}"`, ); }
this.engine = options.engines[this.ext];
this.path = this.lookup(fileName); }
resolve(dir: string, file: string) { let path = join(dir, file); let stat = tryStat(path);
if (stat && stat.isFile) { return path; }
const ext = this.ext; path = join(dir, basename(file, ext), `index${ext}`); stat = tryStat(path);
if (stat && stat.isFile) { return path; } }
lookup(name: string) { const roots = [].concat(this.root); let path;
for (let i = 0; i < roots.length && !path; i++) { const root = roots[i]; const loc = resolve(root, name); const dir = dirname(loc); const file = basename(loc); path = this.resolve(dir, file); }
return path; }
async render(options: object, callback: Function) { const out = await this.engine(this.path, options); callback(undefined, out); }}