import {createLogger} from "@gongt/ts-stl-library/debug/create-logger"; import {LOG_LEVEL} from "@gongt/ts-stl-library/debug/levels"; import {GlobalVariable} from "@gongt/ts-stl-library/pattern/global-page-data"; import {ApiResponse} from "@gongt/ts-stl-library/request/protocol"; import {ERequestType} from "@gongt/ts-stl-library/request/request"; import {ErrorResponse} from "@gongt/ts-stl-library/request/request-error"; import {Request, Router} from "express-serve-static-core"; import {readFileSync} from "fs"; import {resolve} from "path"; import {RequestContext} from "./base/context"; import {ExpressHandler} from "./base/handler"; import {AssignFunction, AssignObjectFunction, MultiValueResponseWrapper} from "./base/response-wrapper"; import {HtmlContainer, RenderContext} from "./middlewares/html-render"; export class DynamicWebpageHandler extends ExpressHandler> { private container: HtmlContainer; private view: string; constructor(html: HtmlContainer, method: ERequestType, url: string) { super(method, url); this.container = html; } protected instanceContext(req, res) { return new DynamicWebpageRequestContext(req, res, this.container); } registerRouter(route: Router) { if (!this.handler) { this.handler = () => { }; } if (this.view) { this.container.addBody(`<% include ${this.view} %>`); } this.container.compile({ filename: this.fileName, }); super.registerRouter(route); Object.freeze(this); } bodyFromFile(v: string) { this.view = v; } } export class DynamicWebpageRequestContext extends RequestContext implements RenderContext { public assign: AssignFunction; public assignObject: AssignObjectFunction; protected html: HtmlContainer; public readonly global: GlobalVariable; public get variables(): {[key: string]: string} { return this.response.localValue; } public get request(): Request { return this._request_raw; } public readonly response: DynamicWebpageResponseWrapper; constructor(req, res, html: HtmlContainer) { super(req, res); this.html = html; this.global = new GlobalVariable(res); } protected createResponseWrapper(): DynamicWebpageResponseWrapper { const resp = new DynamicWebpageResponseWrapper(this.res, this); this.assign = resp.assign.bind(resp); this.assignObject = resp.assignObject.bind(resp); return resp; } passing(varName: string, data: any) { this.global.set(varName, data); } passingObject(data: any) { this.global.set(data); } runRender() { return this.html.render(this); } } const debugSill = createLogger(LOG_LEVEL.SILLY, 'response'); export class DynamicWebpageResponseWrapper extends MultiValueResponseWrapper { private context: DynamicWebpageRequestContext; protected result: ResType&ApiResponse|ErrorResponse = this.mergeTemplateLocals(); constructor(res, context: DynamicWebpageRequestContext) { super(res); this.context = context; } protected asyncResolve(res: ResType): void { this.assignObject(res); } protected asyncReject(error: any): void { this.internalError(error); } protected _send() { return this.context.runRender().then((text) => { this.response.send(text); }); } }