import {createLogger, debugType} from "@gongt/ts-stl-library/debug/create-logger"; import {LOG_LEVEL} from "@gongt/ts-stl-library/debug/levels"; import {ApiResponse, STATUS_CODE_BASE} from "@gongt/ts-stl-library/request/protocol"; import {ErrorResponse} from "@gongt/ts-stl-library/request/request-error"; import {hintErrorStack} from "@gongt/ts-stl-library/strings/hint-error-stack"; import {RequestContext} from "./base/context"; import {ExpressHandler} from "./base/handler"; import {AssignFunction, AssignObjectFunction, MultiValueResponseWrapper} from "./base/response-wrapper"; export class JsonApiHandler extends ExpressHandler> { protected instanceContext(req, res) { res.setHeader('Content-Type', 'application/json; charset=utf-8'); return new JsonApiRequestContext(req, res); } } export class JsonApiRequestContext extends RequestContext { public assign: AssignFunction; public assignObject: AssignObjectFunction; public readonly response: JsonApiResponseWrapper; protected createResponseWrapper(): JsonApiResponseWrapper { const resp = new JsonApiResponseWrapper(this.res); this.assign = resp.assign.bind(resp); this.assignObject = resp.assignObject.bind(resp); return resp; } } const debugSill = createLogger(LOG_LEVEL.SILLY, 'response'); export class JsonApiResponseWrapper extends MultiValueResponseWrapper { result: (ResType&ApiResponse)|ErrorResponse = {} as any; redirect(target: string, permanent: boolean = false) { throw new TypeError('do not allow json api redirect.'); } protected asyncResolve(res: ResType): void { this.assignObject(res); } protected asyncReject(error: any): void { this.internalError(error); } protected _send() { // debugSill('???', this.result) if (this.result.status === STATUS_CODE_BASE.NO_RESPONSE) { debugSill(' added STATUS_CODE_BASE.SUCCESS as `status`'); this.result.status = STATUS_CODE_BASE.SUCCESS; } if (debugSill.enabled) { debugSill(' with json: %j', debugType(this.result)); } let data: string; try { data = JSON.stringify(this.result); } catch (e) { hintErrorStack(e.stack); console.error(this.result); throw e; } this.response.send(data); } }