import * as plugins from './plugins.js'; import { VirtualStream } from './classes.virtualstream.js'; import { TypedResponseError } from './classes.typedresponseerror.js'; import { TypedRouter } from './classes.typedrouter.js'; import { TypedTarget } from './classes.typedtarget.js'; const webrequestInstance = new plugins.webrequest.WebRequest(); export class TypedRequest { /** * in case we post against a url endpoint */ public urlEndPoint?: string; /** * in case we post against a TypedTarget */ typedTarget: TypedTarget; public method: string; /** * @param postEndPointArg * @param methodArg */ constructor(postTarget: string | TypedTarget, methodArg: T['method']) { if (typeof postTarget === 'string') { this.urlEndPoint = postTarget; } else { this.typedTarget = postTarget; } this.method = methodArg; } /** * fires the request */ public async fire(fireArg: T['request'], useCacheArg: boolean = false): Promise { let payloadSending: plugins.typedRequestInterfaces.ITypedRequest = { method: this.method, request: fireArg, response: null, correlation: { id: plugins.isounique.uni(), phase: 'request', }, }; // lets preprocess the payload payloadSending = VirtualStream.encodePayloadForNetwork(payloadSending, { sendMethod: (payloadArg: plugins.typedRequestInterfaces.IStreamRequest) => { return this.postTrObject(payloadArg) as Promise; } }); let payloadReceiving: plugins.typedRequestInterfaces.ITypedRequest; payloadReceiving = await this.postTrObject(payloadSending, useCacheArg); // lets preprocess the response payloadReceiving = VirtualStream.decodePayloadFromNetwork(payloadReceiving, { sendMethod: (payloadArg: plugins.typedRequestInterfaces.IStreamRequest) => { return this.postTrObject(payloadArg) as Promise; } }); return payloadReceiving.response; } private async postTrObject(payloadSendingArg: plugins.typedRequestInterfaces.ITypedRequest, useCacheArg: boolean = false) { let payloadReceiving: plugins.typedRequestInterfaces.ITypedRequest; if (this.urlEndPoint) { const response = await webrequestInstance.postJson( this.urlEndPoint, payloadSendingArg, useCacheArg ); payloadReceiving = response; } else { payloadReceiving = await this.typedTarget.post(payloadSendingArg); } if (payloadReceiving.error) { console.error( `method: >>${this.method}<< got an ERROR: "${payloadReceiving.error.text}" with data ${JSON.stringify( payloadReceiving.error.data, null, 2 )}` ); if (!payloadReceiving.retry) { throw new TypedResponseError(payloadReceiving.error.text, payloadReceiving.error.data); } return null; } if (payloadReceiving.retry) { console.log( `server requested retry for the following reason: ${payloadReceiving.retry.reason}` ); await plugins.smartdelay.delayFor(payloadReceiving.retry.waitForMs); // tslint:disable-next-line: no-return-await payloadReceiving = await this.postTrObject(payloadSendingArg, useCacheArg); } return payloadReceiving; } }