import * as path from 'path'; import * as Loader from 'pinusmod-loader'; import { LoaderPathType } from 'pinusmod-loader'; import * as pathUtil from '../util/pathUtil'; import * as crypto from 'crypto'; import { Application } from '../application'; import { IComponent } from '../interfaces/IComponent'; import { listEs6ClassMethods } from 'pinusmod-rpc'; // app.set('dictionaryConfig',{dict,ignoreAutoRouter}) export interface DictionaryComponentOptions { dict?: string; // 不自动按照路由生成router,仅使用 config/dictionary 内的路由. // 这样路由的 id 就可以通过dictionary的顺序来控制了,方便proto变更不影响原顺序id (为也热更新考虑) // 另外这样也少一次load handler ignoreAutoRouter?: boolean; } function canResolve(path: string) { try { require.resolve(path); } catch (err) { return false; } return true; } export class DictionaryComponent implements IComponent { app: Application; dict: { [key: string]: number } = {}; abbrs: { [key: string]: string } = {}; userDicPath: string; version = ''; name = '__dictionary__'; ignoreAutoRouter: boolean; constructor(app: Application, opts: DictionaryComponentOptions) { this.app = app; // Set user dictionary let p = path.join(app.getBase(), '/config/dictionary'); if (!!opts && !!opts.dict) { p = opts.dict; } if (!!opts) { this.ignoreAutoRouter = !!opts.ignoreAutoRouter; } if (canResolve(p)) { this.userDicPath = p; } } start(cb: () => void) { let servers = this.app.get('servers'); let routes = []; if (!this.ignoreAutoRouter) { // Load all the handler files for (let serverType in servers) { let p = pathUtil.getHandlerPath(this.app.getBase(), serverType); if (!p) { continue; } let handlers = Loader.load(p, this.app, false, false, LoaderPathType.PINUS_HANDLER); for (let name in handlers) { let handler = handlers[name]; let proto = listEs6ClassMethods(handler); for (let key of proto) { routes.push(serverType + '.' + name + '.' + key); } } } } // Sort the route to make sure all the routers abbr are the same in all the servers routes.sort(); console.warn('after start all server, use route dictionary :\n', routes.join('\n')); let abbr; let i; for (i = 0; i < routes.length; i++) { abbr = i + 1; this.abbrs[abbr] = routes[i]; this.dict[routes[i]] = abbr; } // Load user dictionary if (!!this.userDicPath) { let userDic = require(this.userDicPath); abbr = routes.length + 1; for (i = 0; i < userDic.length; i++) { let route = userDic[i]; this.abbrs[abbr] = route; this.dict[route] = abbr; abbr++; } } this.version = crypto.createHash('md5').update(JSON.stringify(this.dict)).digest('base64'); process.nextTick(cb); } getDict() { return this.dict; } getAbbrs() { return this.abbrs; } getVersion() { return this.version; } }