UNPKG

@lionrockjs/central

Version:

Node.js MVC framework inspire from PHP Kohana Framework

127 lines (126 loc) 4.81 kB
import Central from '../../Central.mjs'; import { dirname, join } from 'node:path'; import { readdirSync, statSync, existsSync } from 'node:fs'; import { fileURLToPath, pathToFileURL } from 'node:url'; import CascadeFileLoader from '../CascadeFileLoader.mjs'; export default class HelperPath { constructor() { } modules = new Map(); loader = new CascadeFileLoader({ ignoreList: [/^\./, /^index/, /^init/, /^readme/], pathHandler: (path) => { const classesPath = join(path, 'classes'); try { if (existsSync(classesPath) && statSync(classesPath).isDirectory()) { return classesPath; } } catch (e) { } return path; } }); viewLoader = new CascadeFileLoader({ ignoreList: [/^\./, /^readme/], pathHandler: (path) => path + '/../views' }); get fileList() { return this.loader.fileList; } get templateList() { return this.viewLoader.fileList; } init(EXE_PATH, APP_PATH = null, VIEW_PATH = null, modules = []) { this.loader.fileList.clear(); this.modules.clear(); this.viewLoader.fileList.clear(); Central.EXE_PATH = EXE_PATH.replace(/\/$/, ''); Central.APP_PATH = (APP_PATH || `${Central.EXE_PATH}/application`).replace(/\/$/, ''); Central.VIEW_PATH = (VIEW_PATH || `${Central.EXE_PATH}/views`).replace(/\/$/, ''); // 1. Modules (Lowest Priority) this.addModules(modules); // 2. Scan APP_PATH (High Priority) if (Central.APP_PATH) { this.loader.scanDir(Central.APP_PATH + '/classes'); } // 3. Scan VIEW_PATH (Highest Priority for views) if (Central.VIEW_PATH) { this.viewLoader.scanDir(Central.VIEW_PATH); } // 4. Scan EXE_PATH/modules try { const modulesDir = join(Central.EXE_PATH, 'modules'); const stat = statSync(modulesDir); if (stat.isDirectory()) { const dirs = readdirSync(modulesDir); for (const dir of dirs) { if (dir.startsWith('.')) continue; const modulePath = join(modulesDir, dir); try { if (statSync(modulePath).isDirectory()) { const initFile = join(modulePath, 'init.mjs'); if (statSync(initFile).isFile()) { this.modules.set(modulePath, { filename: pathToFileURL(initFile).href }); const classesPath = join(modulePath, 'classes'); try { if (statSync(classesPath).isDirectory()) { this.loader.scanDir(classesPath); } else { this.loader.scanDir(modulePath); } } catch (e) { this.loader.scanDir(modulePath); } } } } catch (e) { // ignore } } } } catch (e) { // ignore } } async reloadModuleInit() { const initFiles = [...this.modules.keys()].map(x => `${x}/init.mjs`); for (let i = 0; i < initFiles.length; i++) { const file = initFiles[i]; if (!existsSync(file)) continue; try { await import(file); } catch (e) { Central.log(e); } } } resolve(pathToFile) { if (pathToFile.includes('../')) throw new Error('invalid require path'); const file = this.loader.resolve(pathToFile); if (!file) { throw new Error(`Resolve path error: path ${pathToFile} not found.`); } return file; } resolveView(viewName) { return this.viewLoader.resolve(viewName); } addModules(modules) { this.viewLoader.addModules(modules); this.loader.addModules(modules); modules.forEach(m => { if (!m) return; const module = m.default || m; if (!module.filename) return; const dir = dirname(fileURLToPath(module.filename)); this.modules.set(dir, module); }); } }