import * as fs from 'fs'; import * as nodePath from 'path'; import { FileConfigNodeFileResourceServiceOptions, IFileConfigNode } from './types'; import { getFsStats, merge } from '../lib'; const defaultOptions: FileConfigNodeFileResourceServiceOptions = { dirBaseName: 'resources', }; export class FileConfigNodeFileResourceService { public get path(): string { if (!this._path) { // let configRootPath: string; const fileConfigNodeRootPathStats = getFsStats(this.fileConfigNode.path); if (fileConfigNodeRootPathStats) { const configRootPath = fileConfigNodeRootPathStats.isDirectory() ? this.fileConfigNode.path : nodePath.dirname(this.fileConfigNode.path); this._path = nodePath.join(configRootPath, this.options.dirBaseName); } else { // don't think this should be possible as would have already been hit by ConfigNode throw new Error(`FileConfigNodeFileResourceService Root Path Not Found`); } } return this._path; } public readonly options: FileConfigNodeFileResourceServiceOptions; private _path: string; constructor( private fileConfigNode: IFileConfigNode, options: FileConfigNodeFileResourceServiceOptions = defaultOptions ) { this.options = merge([defaultOptions, options]); } /** * Resolves first existing search paths matching passed path and subpath * @param path relative path from search path to find * @returns path */ public resolvePath = (...path: string[]): string | null => { const subPathToFind = nodePath.join(...path); const fullPathToFind = nodePath.join(this.path, subPathToFind); if (fs.existsSync(fullPathToFind)) { return fullPathToFind; } else { const inheritedNodes = this.fileConfigNode.resolveInheritedNodes(); for (const inheritedNode of inheritedNodes) { // tslint:disable-next-line: no-string-literal if (inheritedNode['fileResources']) { const node = (inheritedNode as unknown) as IFileConfigNode; const found = node.fileResources.resolvePath(...path); if (found) { return found; } } } } return null; }; }