95 lines
2.2 KiB
TypeScript
95 lines
2.2 KiB
TypeScript
import { IMessage } from './message';
|
|
|
|
/**
|
|
* Message data object for staged handling
|
|
* Response value is always mandatory.
|
|
*/
|
|
export interface IMessageData {
|
|
text?: string;
|
|
data?: any;
|
|
compose?: any[];
|
|
value: any;
|
|
}
|
|
|
|
export type IMessageHandler = (data: IMessageData | string, reject: (error: Error) => void, next: IMessageHandler) => void;
|
|
|
|
/**
|
|
* Staged messaging handler
|
|
*/
|
|
export class MessageResolver {
|
|
private handlers: IMessageHandler[] = [];
|
|
|
|
public static textFormatter(text: string | undefined, value: any): string {
|
|
let stri = text || '';
|
|
if (Array.isArray(value) || typeof value === 'object') {
|
|
stri = stri.replace(/%([a-z]+)?(\d+)?/ig, (substr: string, word?: string, nr?: number): string => {
|
|
if (nr && typeof nr === 'string') {
|
|
nr = parseInt(nr as 'string', 10);
|
|
}
|
|
|
|
if (Array.isArray(value) && nr != null) {
|
|
return value[nr];
|
|
}
|
|
|
|
if (!word) {
|
|
return substr;
|
|
}
|
|
|
|
const val = value[word];
|
|
if (Array.isArray(val) && nr) {
|
|
return val[nr];
|
|
}
|
|
|
|
return val;
|
|
});
|
|
} else if (value === 'string') {
|
|
if (!text) {
|
|
stri = value;
|
|
} else {
|
|
text += ' ' + value;
|
|
}
|
|
}
|
|
return stri;
|
|
}
|
|
|
|
constructor(public msg: IMessage) {}
|
|
|
|
/**
|
|
* Inject a middleware message handler
|
|
* @param fn Message handler function
|
|
*/
|
|
use(fn: IMessageHandler): void {
|
|
this.handlers.push(fn);
|
|
}
|
|
|
|
/**
|
|
* Resolve the message. Call this only from the last plugin in the chain.
|
|
* @param data Message response data
|
|
*/
|
|
resolve(data: IMessageData | string, ...rest: any[]): void {
|
|
const ist = this.handlers.pop();
|
|
if (!this.handlers.length || !ist) {
|
|
if (typeof data === 'string') {
|
|
this.msg.resolve(data, ...rest);
|
|
return;
|
|
}
|
|
if (data.compose && Array.isArray(data.compose)) {
|
|
this.msg.resolve(data.compose);
|
|
return;
|
|
}
|
|
this.msg.resolve(MessageResolver.textFormatter(data.text, data.value));
|
|
return;
|
|
}
|
|
|
|
ist.call(this, data, this.msg.reject, this.resolve);
|
|
}
|
|
|
|
/**
|
|
* Reject the message. You can call this from anywhere.
|
|
* @param error Error
|
|
*/
|
|
reject(error: Error): void {
|
|
this.msg.reject(error);
|
|
}
|
|
}
|