/* eslint-disable camelcase */ import { parseTextWithRegexList } from "../../utils/regex.js"; import type { Runner } from "../../utils/runner.js"; export interface SysmsgTemplateXmlSchema { content_template: { $: { type: string; }; plain: string; template: string; link_list: { link: [ { $: { name: string; type: string; hidden?: string; }; memberlist?: { member: [ { username?: string; nickname: string; } ]; }; separator?: string; title?: string; usernamelist?: { username: string[]; }; } ]; }; }; } export interface SysmsgTemplateLinkMember { userName?: string, nickName: string, } export type SysmsgTemplateLinkProfile = Array; export interface SysmsgTemplateLinkRevoke { title: string, userNameList: string[], } export type SysmsgTemplateLinkType = "link_profile" | "link_revoke"; export type SysmsgTemplateLinkPayload = SysmsgTemplateLinkProfile | SysmsgTemplateLinkRevoke; export interface SysmsgTemplateLink { name: string, payload: SysmsgTemplateLinkPayload, type: SysmsgTemplateLinkType, } export interface SysmsgTemplateMessagePayload { template: string; templateLinkList: Array; // link list is sorted by template variable name order } /** * xmlToJson will return element instead of array if xml node only contains one child. * @param list */ function toList(list: any): any[] { if (!Array.isArray(list)) { return [ list ]; } else { return list; } } export async function parseSysmsgTemplateMessagePayload(sysmsgTemplateXml: SysmsgTemplateXmlSchema): Promise { const linkList = toList(sysmsgTemplateXml.content_template.link_list.link); const allLinkList = linkList.map((link): SysmsgTemplateLink => { const type = link.$.type as SysmsgTemplateLinkType; let payload: SysmsgTemplateLinkPayload | undefined; if (type === "link_profile") { const memberList = toList(link.memberlist!.member); payload = memberList.map((member: { nickname: string; username?: string; }): SysmsgTemplateLinkMember => { return { nickName: member.nickname, userName: member.username, }; }); } else if (link.$.type === "link_revoke") { payload = { title: link.title!, userNameList: toList(link.usernamelist!.username), }; } else { // handle more link type here } return { name: link.$.name, payload: payload!, type, }; }); const template = sysmsgTemplateXml.content_template.template; const matches = [ ...template.matchAll(/\$(.+?)\$/g) ]; const templateLinkList = matches.map(match => { const linkName = match[1]; return allLinkList.filter((link) => link.name === linkName)[0]!; }); return { template, templateLinkList, }; } export type SysmsgTemplateHandler = (templateLinkList: SysmsgTemplateLink[], matchedRegexIndex: number) => Promise; export async function parseSysmsgTemplate(sysmsgTemplatePayload: SysmsgTemplateMessagePayload, regexList: RegExp[], handler: SysmsgTemplateHandler) : Promise { return parseTextWithRegexList(sysmsgTemplatePayload.template, regexList, async(matchedRegexIndex) => { return handler(sysmsgTemplatePayload.templateLinkList, matchedRegexIndex); }); } export function createSysmsgTemplateRunner(sysmsgTemplatePayload: SysmsgTemplateMessagePayload, regexList: RegExp[], handler: SysmsgTemplateHandler): Runner { return async() => parseSysmsgTemplate(sysmsgTemplatePayload, regexList, handler); }